这是一个非常简单的程序:
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])
Run Code Online (Sandbox Code Playgroud)
这是我期待的输出:
[[], [], []]
[1]
[2]
[3]
Run Code Online (Sandbox Code Playgroud)
但相反,我得到了这个:
[[], [], []]
[1, 2, 3]
[1, 2, 3]
[1, 2, 3]
Run Code Online (Sandbox Code Playgroud)
我真的没有到达这里!
Igo*_*bin 12
你必须这样做
a = [[] for i in xrange(3)]
Run Code Online (Sandbox Code Playgroud)
不
a = [[]]*3
Run Code Online (Sandbox Code Playgroud)
它现在有效:
$ 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]
Run Code Online (Sandbox Code Playgroud)
当你做类似的事情时,a = [[]]*3你会在列表中[]三次获得相同的列表.同样意味着当您更改其中一个时,您将更改所有这些(因为只有一个列表被引用三次).
您需要创建三个独立列表来规避此问题.你可以通过列表理解来做到这一点.您在此构造一个由独立空列表组成的列表[].新的空列表将在每次迭代在创建xrange(3)(之间的差别range,并xrange没有在这种情况下很重要,但xrange有一点更好,因为它不会产生号码的完整列表,只是返回迭代器对象,而不是).
当你写:
a = [[]]*3
Run Code Online (Sandbox Code Playgroud)
您不会制作内部空列表的3个副本,而是对同一个对象进行3次引用.
同样的,如果你这样做:
b = [1,2,3]
c = b
c.append(4)
print b
Run Code Online (Sandbox Code Playgroud)
你得到输出:
[1, 2, 3, 4]
Run Code Online (Sandbox Code Playgroud)
这是因为b和c是两个不同的引用(可以说两个不同的名称)到同一个列表.您可以从任何引用更改对象,但是您将看到所有引用的结果,因为它们指向相同的内容.
您的方法的基本问题是,当您将列表乘以3时,结果列表包含三个相同的列表.所以a[0],a[1]并且a[2]所有人都提到同样的事情.当您附加到其中任何一个时,您将附加到相同的列表.这就是为什么你的append()通话效果似乎是三倍的原因.
而是生成列表列表而不引用相同的列表.例如,您可以使用列表推导,就像这样.
[[] for i in range(3)]
Run Code Online (Sandbox Code Playgroud)