6

这是一个非常简单的程序:

 a = [[]]*3

 print str(a)

 a[0].append(1)
 a[1].append(2)
 a[2].append(3)

 print str(a[0])
 print str(a[1])
 print str(a[2])

这是我期待的输出:

 [[], [], []]
 [1]
 [2]
 [3]

但相反,我得到了这个:

 [[], [], []]
 [1, 2, 3]
 [1, 2, 3]
 [1, 2, 3]

真的有什么我不明白的!

4

5 回答 5

12

你必须做

a = [[] for i in xrange(3)]

不是

a = [[]]*3

现在它起作用了:

$ cat /tmp/3.py
a = [[] for i in xrange(3)]

print str(a)

a[0].append(1)
a[1].append(2)
a[2].append(3)

print str(a[0])
print str(a[1])
print str(a[2])

$ python /tmp/3.py
[[], [], []]
[1]
[2]
[3]

当你做类似的事情时,a = [[]]*3你会在一个列表中得到相同的列表[]三次。这同样意味着当您更改其中一个时,您会更改所有这些(因为只有一个列表被引用了 3 次)。

您需要创建三个独立的列表来规避这个问题。你可以通过列表理解来做到这一点。您在这里构造一个由独立的空列表组成的列表[]。每次迭代都会创建新的空列表(在这种情况下,和xrange(3)之间的区别并不那么重要;但更好一点,因为它不会生成完整的数字列表,而是返回一个迭代器对象)。rangexrangexrange

于 2012-06-27T05:31:19.500 回答
5

当你写:

a = [[]]*3

您不会制作内部空列表的 3 个副本,而是对同一个对象进行 3 次引用。

同样的方式,如果你这样做:

b = [1,2,3]
c = b
c.append(4)
print b

你得到作为输出:

[1, 2, 3, 4]

那是因为 b 和 c 是对同一个列表的两个不同的引用(您可能会说两个不同的名称)。您可以从任何引用更改对象,但您会看到所有引用的结果,因为它们指向同一事物。

于 2012-06-27T05:33:32.827 回答
5

您的方法的基本问题是,当您将列表乘以三时,结果列表包含三个相同的列表。所以a[0], a[1], 和a[2]都引用同一个东西。当您附加到其中任何一个时,您将附加到同一个列表。这就是为什么你的append()电话的效果似乎是三倍的。

相反,在不引用相同列表的情况下生成列表列表。例如,您可以像这样使用列表推导。

[[] for i in range(3)]
于 2012-06-27T05:34:41.420 回答
2

这会给你一个清晰的想法,在 l 所有对象都具有相同的 id() 并且都是可变的,因此编辑其中任何一个也将自动编辑另一个,因为它们都只是对 id=18671936 和 in 的同一对象的引用m都有不同的id(),所以它们都是不同的对象。

>>> l = [[]]*4
>>> for x in l:
        print(id(x))

18671936 
18671936
18671936
18671936

>>> m=[[],[],[],[]]
>>> for x in m:
        print(id(x))

10022256
18671256
18672496
18631696

所以,你应该像这样创建你的列表:

>>> a=[[] for _ in range(4)]
>>> a[0].append(1)
>>> a[2].append(5)
>>> a
[[1], [], [5], []]
于 2012-06-27T06:03:30.580 回答
1

真的有什么我不明白的!

a = [[]]*3这里的问题是您将列表设置为相同的引用,因为数组和字典都存储为引用。

>>> a = [[]]*3
>>> a[0] is a[1] or a[0] is a[2]
True
>>> a[0] is a[1] or a[0] is a[2] or a[1] is a[2]
True
>>> 

如果你做 a = [{}]*3`,也会发生同样的事情

因此,您必须小心,您可以执行列表理解[[] for _ in xrange(3)]或静态定义所有 3 个数组[[], [], []]

>>> a = [[] for _ in xrange(3)]
>>> a[0] is a[1] or a[0] is a[2] or a[1] is a[2]
False
>>> 
于 2012-06-27T05:39:43.490 回答