Skip to main content
 首页 » 编程设计

Python之列表切片行为的列表

2025年05月04日15soundcode

当我定义一个列表并尝试像这样更改单个项目时:

list_of_lists = [['a', 'a', 'a'], ['a', 'a', 'a'], ['a', 'a', 'a']] 
list_of_lists[1][1] = 'b' 
for row in list_of_lists: 
    print row 

它按预期工作。但是当我尝试使用列表理解来创建列表时:

row = ['a' for range in xrange(3)] 
list_of_lists = [row for range in xrange(3)] 
list_of_lists[1][1] = 'b' 
for row in list_of_lists: 
    print row 

它会导致列表中的整列项目被更改。为什么是这样?如何通过列表推导达到预期的效果?

请您参考如下方法:

想想如果你这样做:

>>> row = ['a' for range in xrange(3)] 
>>> row2 = row 
>>> row2[0] = 'b' 
>>> row 
['b', 'a', 'a'] 

发生这种情况是因为row 和row2 是同一列表 的两个不同名称(您有row is row2) - 您的带有嵌套列表的示例只会稍微掩盖这一点。

要使它们成为不同的列表,您可以让它每次都重新运行列表创建代码,而不是进行变量赋值:

list_of_lists = [['a' for range in xrange(3)] for _ in xrange(3)] 

或者,每次使用完整旧列表的一部分创建一个新列表:

list_of_lists = [row[:] for range in xrange(3)] 

虽然这不能保证对所有序列都适用 - 只是列表切片会为切片创建一个新列表。这不会发生在例如 numpy 数组中——其中的一个切片是数组的一部分的 View 而不是副本。如果您需要处理的不仅仅是列表,请使用 copy 模块:

from copy import copy 
list_of_lists = [copy(row) for range in xrange(3)] 

另外,请注意 range 不是变量的最佳名称,因为它隐藏了内置函数 - 对于像这样的一次性变量,_ 是相当常见的。