我构建了一个3级嵌套列表
#run on Python 3.2.3 32 bit on Win 7
L2=list(0 for i in range(2))
L3=list(L2 for i in range(3))
L4=list(L3 for i in range(4))
#give a new value to the very first number in list:
L4[0][0][0]=5
print("L4:")
print(L4)
#outputs erronously:
#[[[5, 0], [5, 0], [5, 0]], [[5, 0], [5, 0], [5, 0]], [[5, 0], [5, 0], [5, 0]], [[5, 0], [5, 0], [5, 0]]]
明确给出的相同列表
#the same L4 given explicitly:
anotherL4=[[[0, 0], [0, 0], [0, 0]], [[0, 0], [0, 0], [0, 0]], [[0, 0], [0, 0], [0, 0]], [[0, 0], [0, 0], [0, 0]]]
print("anotherL4:")
#give a new value to the very first number:
anotherL4[0][0][0]=5
print(anotherL4)
#outputs correctly:
#[[[5, 0], [0, 0], [0, 0]], [[0, 0], [0, 0], [0, 0]], [[0, 0], [0, 0], [0, 0]], [[0, 0], [0, 0], [0, 0]]]
答案 0 :(得分:3)
你错了。您已经多次复制了引用,这意味着它们实际上都是相同的列表。
答案 1 :(得分:3)
当您编写list(L3 for i in range(4))
时,您告诉它在生成器理解的每次迭代中产生相同的列表L3。当您随后修改该列表时,修改会显示在任何位置,因为它们都是对同一列表的引用。
你可以通过
获得你想要的效果list(list(L3) for i in range(4))
因为使用list(L3)
会创建一个新列表。
答案 2 :(得分:0)
只是详细说明,
a = 1
b = 2
c = [a,b]
a += 1
print c
答案 3 :(得分:0)
您的问题是您构建了一个列表引用列表而不是列表列表。由于引用都指向单个列表,当您改变该单个列表时,所有引用都会显示更改。
L0 = range(3)
L1 = range(3)
print(id(L0)) # prints a number
print(id(L1)) # prints a different number
print(id(L0) == id(L1)) # prints False
print(L0 is L1) # prints False; not same objects
print(L0 == L1) # prints True; values match
# your original code:
L2=list(0 for i in range(2))
L3=list(L2 for i in range(3))
L4=list(L3 for i in range(4))
print(L3[0] is L2) # prints True; L3[0] is a reference to L2
我们可以修复它并使用copy.deepcopy()
明确显示我们正在做的事情:
import copy
L2 = [0 for i in range(2)]
L3 = [copy.deepcopy(L2) for i in range(3)]
L4 = [copy.deepcopy(L3) for i in range(4)]
#give a new value to the very first number in list:
L4[0][0][0]=5
print("L4:")
print(L4)
请注意,我不是使用生成器表达式并将其传递给list()
来强制将其扩展到列表,而是使用上面代码中的列表推导来直接创建列表。
更常见的是,如果你想做这个疯狂的事情,你应该只是嵌套一些列表理解:
L4 = [[[0 for _ in range(2)] for _ in range(3)] for _ in range(4)]
这很清楚我们正在建立一个新的列表列表。如果你使用copy.deepcopy()
,你基本上只是复制一堆零,所以你也可以使用零来构建新的列表。