Python列表错误或我错了吗?

时间:2012-06-03 22:22:55

标签: python list

我构建了一个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]]]

4 个答案:

答案 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(),你基本上只是复制一堆零,所以你也可以使用零来构建新的列表。