Python:如何在列表列表中追加新元素?

时间:2012-06-27 05:29:41

标签: python list

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

 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]

我真的没有到达这里!

5 个答案:

答案 0 :(得分: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之类的操作时,您会在列表中三次获得相同的列表[]相同的意味着当您更改其中一个时,您将更改所有这些(因为只有一个列表被引用三次)。

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

答案 1 :(得分:5)

当你写:

a = [[]]*3

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

同样的,如果你这样做:

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

你得到输出:

[1, 2, 3, 4]

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

答案 2 :(得分:5)

您的方法的基本问题是,当您将列表乘以3时,结果列表包含三个相同列表的 。因此a[0]a[1]a[2]都引用相同的内容。当您附加到其中任何一个时,您将附加到相同的列表。这就是为什么append()来电的影响似乎很重要。

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

[[] for i in range(3)]

答案 3 :(得分:2)

这将给你一个清晰的想法,在l所有对象都具有相同的id()并且所有对象都是可变的,因此编辑它们中的任何一个也将自动编辑其他对象,因为它们都只是引用具有id =的相同对象18671936和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], []]

答案 4 :(得分: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
>>> 

如果您执行= [{}] * 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
>>>