我是编程新手,我有这个基本问题我无法解决。我尽可能地简化了它。在这个简化版本中,我正在迭代一个空列表。我只想将索引存储在“对称矩阵”中:
n = 2
B = [[None] * n] * n
print B, "\n"
for i in range(n):
for j in range(n):
B[i][j] = [i, j]
print B
最初,列表如下所示:
[[None, None], [None, None]]
循环结束后,我希望打印输出为:
[[[0, 0], None], [None, None]]
[[[0, 0], [0, 1]], [None, None]]
[[[1, 0], [0, 1]], [[1, 0], None]]
[[[1, 0], [1, 1]], [[1, 0], [1, 1]]]
相反,我明白了:
[[[0, 0], None], [[0, 0], None]]
[[[0, 0], [0, 1]], [[0, 0], [0, 1]]]
[[[1, 0], [0, 1]], [[1, 0], [0, 1]]]
[[[1, 0], [1, 1]], [[1, 0], [1, 1]]]
我错过了什么?谢谢你帮帮忙......
答案 0 :(得分:3)
您的初始化会创建对同一列表的两个引用:
n=2
B=[[None]*n]*n
for x in B:
print id(x)
输出:
4534759576
4534759576
答案 1 :(得分:3)
您需要的是代替您定义B
的当前方式,而不是n
子列表的“新鲜”实例:
B = [[None] * n for _ in range(n)]
相当于但更短,(对于Pythonista)比以下更具可读性
B = []
for _ in range(n):
B.append([None] * n)
这是因为Python中的列表不是值而是对象;即默认情况下不会复制它们。例如:
>>> a = []
>>> b = [a, a] # list of 2 items, both pointing to the same list instance
>>> b[0].append(1) # b[0] refers to the same list instance also referenced by a
>>> print b
[[1], [1]]
,而:
>>> b = [[], []] # list of 2 distinct sublists
>>> b[0].append(1)
>>> print b
[[1], []]
如果您将该知识应用于
B = [[None] * n] * n
您会看到构造中存在错误 - 您正在创建一个包含另一个n
None
值列表的列表;然后你“升迁”列表以包含n
这样的列表;但是,将使用相同的列表实例,就像上面的更简单的例子一样。
PS 更准确地说,Python中的所有内容都是一个对象而不是一个值,除非对象是不可变的,例如int
s和float
s和{ {1}}等等,就好像它们是值并且总是被复制 - 这是因为如果一个对象是不可变的,你可能会假装对它的新引用是它的新副本,因为它看起来是一样的并且无法修改。
答案 2 :(得分:1)
以下是您可以做的,您想要的:
n=2
B = [[None for i in range(n)] for i in range(n)]
print B, "\n"
for i in range(n):
for j in range(n):
B[i][j] = [i, j]
print B
答案 3 :(得分:1)
了解您在使用[[None]*n]*n
方法时创建包含共享引用的列表的关键是理解这里发生的事情。看看代码所做的this visualisation,它应该让事情变得更清晰。 This blog post还解释了名称和值如何在Python中起作用。