2

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

4 回答 4

3

你错了。您已多次复制引用,这意味着它们实际上都是相同的列表。

于 2012-06-03T22:24:00.283 回答
3

当您编写 时list(L3 for i in range(4)),您是在告诉它在生成器理解的每次迭代中产生相同的列表 L3。当您随后修改该列表时,修改会随处显示,因为它们都是对同一个列表的引用。

你可以通过做得到你想要的效果

list(list(L3) for i in range(4))

因为 usinglist(L3)创建了一个新列表。

于 2012-06-03T22:25:37.323 回答
0

只是为了详细说明,

a = 1
b = 2
c = [a,b]
a += 1
print c
于 2012-06-03T22:25:51.237 回答
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()你基本上只是复制一堆零,所以你不妨只使用零构建新列表。

于 2012-06-03T22:46:20.590 回答