74

可能重复:
Python 列表中的意外功能

所以我对 Python 比较陌生,并且在使用 2D 列表时遇到了麻烦。

这是我的代码:

data = [[None]*5]*5
data[0][0] = 'Cell A1'
print data

这是输出(为便于阅读而格式化):

[['Cell A1', None, None, None, None],
 ['Cell A1', None, None, None, None],
 ['Cell A1', None, None, None, None],
 ['Cell A1', None, None, None, None],
 ['Cell A1', None, None, None, None]]

为什么每一行都被赋值?

4

3 回答 3

106

这将创建一个包含五个对同一列表的引用的列表:

data = [[None]*5]*5

使用类似这样的东西来创建五个单独的列表:

>>> data = [[None]*5 for _ in range(5)]

现在它可以满足您的期望:

>>> data[0][0] = 'Cell A1'
>>> print data
[['Cell A1', None, None, None, None],
 [None, None, None, None, None],
 [None, None, None, None, None],
 [None, None, None, None, None],
 [None, None, None, None, None]]
于 2010-04-29T17:49:49.687 回答
18

作为序列类型的python库参考,其中包括列表,说

另请注意,副本很浅;嵌套结构不会被复制。这常常困扰着新的 Python 程序员。考虑:

>>> lists = [[]] * 3
>>> lists
  [[], [], []]
>>> lists[0].append(3)
>>> lists
  [[3], [3], [3]]

发生的事情是 [[]] 是一个包含一个空列表的单元素列表,因此 [[]] * 3 的所有三个元素都是(指向)这个单个空列表的。修改列表的任何元素都会修改此单个列表。

您可以通过这种方式创建不同列表的列表:

>>> lists = [[] for i in range(3)]  
>>> lists[0].append(3)
>>> lists[1].append(5)
>>> lists[2].append(7)
>>> lists
  [[3], [5], [7]]
于 2010-04-29T17:55:13.730 回答
2

在 python 中,每个变量都是一个对象,因此也是一个引用。您首先创建了一个包含 5 个 None 的数组,然后您构建了一个包含 5 次相同对象的数组。

于 2010-04-29T17:51:32.367 回答