Python的*运算符如何工作?

时间:2013-06-04 16:26:32

标签: list python-2.7 operators

我使用python的*创建一个2-dimetion列表[[0] * 10] * 10,默认值为0。 但是当我将第一个元素设置为1时,第一个列的所有元素都发生了1,为什么?

使用append创建列表时不会发生这种情况(参见下面的变量数据)。

#!/bin/env python
#encoding=utf8

width = 10
height = 10

data = []
for i in xrange(width):
    data.append([0 for j in xrange(height)])

data2 = [[0]*width]*height

print "before:",data == data2
data[0][0] = 1
data2[0][0] = 1
print "after:",data == data2

print "actually:"
print data
print data2

输出:

before: True
after: False
actually:
[[1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
[[1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]]

2 个答案:

答案 0 :(得分:1)

列表中的*运算符将重复列表中的对象。但它不会创建对象的副本,它会重复实际的对象本身。

区别是微妙的,很多时候你不会注意到它。如果对象是不可变的,例如数字或字符串,那么您所能做的就是用不同的对象替换对象,然后列表的成员将不再是同一个对象。

当列表中的对象可以被修改时,例如另一个列表,对该对象的任何修改都会反映在列表中的所有其他重复引用中。

有一个尴尬的解决方法:

data3 = [[0]*width for i in range(height)]

答案 1 :(得分:0)

下面:

[[0]*width]

您只创建一个列表[0],然后创建另一个列表,其中包含对该单个对象的width个引用。关键是*运算符只评估其操作数一次。

这里:

for i in xrange(width):
    data.append([0 for j in xrange(height)])

您正在为每个迭代创建一个新列表,然后添加该列表。