Python列表推导式:创建二维数组

9

可能是重复问题:
Python 2D列表在尝试修改单个值时有奇怪的行为

大家好,

我想知道以下两个语句是否相同?

a = [[0]*3]*3
b = [[0]*3 for i in range(3)]

结果看起来相同,但其中一种方法是否更好?这里有什么区别。
非常感谢您的帮助。
nos

4
确实有成千上万的问题涉及到这个确切的话题... - JBernardo
3个回答

18

它们并不相同

>>> a[1][2] = 5
>>> a
>>> [[0, 0, 5], [0, 0, 5], [0, 0, 5]]


>>> b[1][2] = 5
>>> b
>>> [[0, 0, 0], [0, 0, 5], [0, 0, 0]]

第一个创建的是指向单个内部数组的指针的外部数组,而第二个实际上创建了3个不同的数组。


1
我正在打完全相同的东西。给你加一分。 - Makoto
是的,在第一个例子中,所有三个数组都是同一个对象。例如,如果使用整数而不是 [[]]*5,例如 [1]*5,每个位置都会使用一个新的整数。 - Rusty Rob
3
这些不是Python数组,而是Python列表。 - joaquin

7
不,它们不同。 在第一个列表中,有三个相同的列表,引用相同;而在第二个列表中,有三个不同的列表。
>>> a = [[0]*3]*3
>>> a
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> a[0][0]=1

>>> a
[[1, 0, 0], [1, 0, 0], [1, 0, 0]]


>>> b = [[0]*3 for i in range(3)]
>>> b
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> b[0][0] = 1

>>> b
[[1, 0, 0], [0, 0, 0], [0, 0, 0]]

尝试执行 a[0].append("foo") - Fred Foo

0
这是一个经典的浅拷贝与深拷贝的案例,如此处在Python文档中所解释的:)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接