添加到列表与增量
在Python中:
element = element + [0]
应该等于:
element += [0]
为什么一个会改变列表,而另一个不会呢?这里有个例子:
>>> a = [[0, 0], [0,0]]
>>> for element in a:
... element = element + [0]
...
>>> a
[[0, 0], [0, 0]]
a没有被改变。但是如果我增加:
>>> a = [[0, 0], [0,0]]
>>> for element in a:
... element += [0]
...
>>> a
[[0, 0, 0], [0, 0, 0]]
a就被改变了。
谢谢,
Frank
3 个回答
补充一下其他人说的内容,这些语句的作用是有区别的:
element = element + [0]
做了什么
element = element.__add__([0])
而
element += [0]
做了什么
element = element.__iadd__([0])
__iadd__()
这个方法可以决定返回什么:是修改过的原对象,还是一个新对象。
对于不可变对象,它必须返回一个不同的对象(例如,a = b = 8; a += 9
结果是 a 和 b 不相同
)。
但对于可变对象,比如列表,它通常会修改原来的对象:
a = b = []
a += [8]
结果是 a 和 b 是相同的
。
这种不同的行为在你的循环中也会体现出来:
for element in a:
element = element + [0]
这意味着 name
这个 element
被重新绑定到了一个不同的对象;原来的对象没有被改变。
for element in a:
element += [0]
原来的对象,仍然在外部列表 a
中,也会被修改。element
被重新赋值这件事并不重要;它并没有被使用。
在第一个例子中,element = element + [0],你实际上是在创建一个新的列表。
而在第二个例子中,element += [0],你是在修改一个已经存在的列表。
因为列表 a 中的每个列表都是指向元素的指针,所以只有修改这些元素才会真正改变内容。(也就是说,创建一个新列表并不会改变 a 中的指针。)
如果我们用一个简单的例子来展示列表是如何工作的,这一点会更清楚:
>>> a = [1, 2, 3]
>>> b = a
>>> a = [4, 5, 6]
>>> a
[4, 5, 6]
>>> b
[1, 2, 3]
>>> a = [1, 2, 3]
>>> b = a
>>> a += [4, 5, 6]
>>> b
[1, 2, 3, 4, 5, 6]
>>> a
[1, 2, 3, 4, 5, 6]
把一个变量指向一个列表,其实就是在指向这个列表的地址。
这是一个有趣的现象,跟 +=
这个操作符有关,它会调用 __iadd__
方法,而不是 __add__
方法。
比如说,语句 x = x + y
实际上等同于 x = x.__add__(y)
,而 x += y
则等同于 x = x.__iadd__(y)
。
这样一来,list
类就可以通过扩展现有的列表来优化 +=
的操作(也就是说,x += y
大致上等同于 x.extend(y)
),而不是创建一个全新的列表(这正是 +
操作需要做的事情)。
举个例子:
>>> a = [1, 2, 3] >>> original_a = a >>> b = [1, 2, 3] >>> original_b = b >>> a += [4] >>> b = b + [4] >>> a is original_a True >>> b is original_b False
你可以看到,使用 +=
时,左边的对象保持不变(也就是说,没有 创建一个新的列表),而使用 +
时则会创建一个新的列表(也就是说,是 创建了一个新的列表)。
想了解更多,可以查看:http://docs.python.org/library/operator.html#operator.iadd,以及文档中 operator.iadd
相关段落的内容。