我已经在Python和JS上测试了这个例子,由于结果相同,因此仅提供前者。考虑代码段
a = []
b = []
for i in range(3):
for j in range(2):
a.append(0)
print("a = ",a)
b.append(a)
print("b = ",b)
将a
用作列表时,结果为[[0,0,0,0,0,0],[0,0,0,0,0,0],[0,0,0,0,0,0]]
。如果a
是字符串,
a = ""
b = []
for i in range(3):
for j in range(2):
a+= "0"
print("a = ",a)
b.append(a)
print("b = ",b)
这给了['00','0000','000000']
.
使用列表编写代码时,我期待输出[[0,0],[0,0,0,0],[0,0,0,0,0,0]
,类似于字符串,但呈列表形状。我一直试图解决这个问题,但无济于事。我错过了什么?
您正在添加对列表的引用,而不是实际列表。改用
b.append(a[:])
当a
是一个列表时,调用b.append(a)
会将对a
的引用附加到b
的末尾。然后,下次运行 for 循环时,a
会发生变化,因此b
中对a
的所有引用也会更改。
与列表不同,字符串是不可变的,因此b.append(a)
a
的副本附加到b
的末尾。您可以将代码更改为b.append(a[:])
以获取使用字符串查找的行为,这会在追加之前创建a
的副本。
问题是 a 是对每个循环中使用的相同数组的引用。您已将 a 附加到 b,但随后在下一次迭代中引用相同的数组。
b.append(list(a))
这会创建您尝试追加的数组的副本。
你缺少什么 ->追加如何工作以及你正在追加什么。
您正在为每次迭代添加对b
即 B 外观的引用
b = [reference_to_a, reference_to_a, referemce_to_a]
最后,对 A 的引用是最新的,即上次迭代的引用。
即无论上次迭代的值是什么,它都将与所有值相同。
您可以在所有情况下通过检查对象的id
来验证这一点。
如何解决这个问题 ->使用a
deepcopy
并附加它或创建一个新的a
元素列表。
您可以验证上述声明
>>> a = [1]
>>> b = [1]
>>>
>>> a.append(b)
>>> a.append(b)
>>> a.append(b)
>>> a.append(b)
>>>
>>> a
[1, [1], [1], [1], [1]]
>>>
>>>
>>> b.append(2)
>>> a
[1, [1, 2], [1, 2], [1, 2], [1, 2]]
所以要解决这个用途
a.append(deepcopy(b))
您可以验证这一点
>>>
>>> a =[1]
>>> b = [1]
>>>
>>> from copy import deepcopy
>>>
>>> a.append(deepcopy(b))
>>> a
[1, [1]]
>>> b
[1]
>>> b.append(3)
>>> a
[1, [1]]
>>> b
[1, 3]
>>> a.append(deepcopy(b))
>>> a
[1, [1], [1, 3]]
>>> b.append(5)
>>> a
[1, [1], [1, 3]]
>>> a.append(deepcopy(b))
>>> a
[1, [1], [1, 3], [1, 3, 5]]