编辑:( 以解决您对问题的编辑引起的其他问题):
a = a + b和
a += b不一样的操作。前者执行
a.__add__(b),后者执行
a.__iadd__(b)(“就地添加”)。
两者之间的区别在于,前者始终创建一个新对象(并将名称
a重新绑定到该新对象),而后者则就地修改该对象(如果可以,并且可以使用列表,则可以)。
为了说明这一点,只需查看对象的地址即可:
>>> a = [1, 2]>>> id(a)34660104>>> a = a + [a]>>> id(a)34657224>>> id(a[2])34660104
“新”
a是从头开始构造的,首先从旧列表中获取值
a,然后将对旧对象的引用连接到该列表。
与此相比:
>>> a = [1, 2]>>> id(a)34658632>>> a += [a]>>> id(a)34658632>>> id(a[2])34658632
(旧答案,解释循环引用):
考虑一下:
>>> a = [1, 2]; a += a>>> a[1, 2, 1, 2]>>> a = [1, 2]; a.extend(a)>>> a[1, 2, 1, 2]>>> a = [1, 2]; a += [a]>>> a[1, 2, [...]]>>> a = [1, 2]; a.append(a)>>> a[1, 2, [...]]
因此,总结一下第一部分:
对于列表,
a += a相当于调用就地
a.extend(a)修改
a,并添加在
a此操作开始时找到的元素的副本。
相反地,
a += [a]对应于
a.append(a),两者都创建对列表的引用
a(即,一个指向在其存储器地址),并添加 其
到列表中。构成所谓的“循环参考”。
如果您要查看此时的内部表示
a,它将看起来像这样:
a: Reference to a list object at address 0xDEADBEEFa[0]: Reference to the integer object "1"a[1]: Reference to the integer object "2"a[2]: Reference to the same list object at address 0xDEADBEEF
旧的Python版本(1.5.1之前的版本)不够聪明,无法检测到它,因此,如果执行a
print a,则会
[1, 2, [1, 2, [1, 2,[1, 2, [1, 2, [1, 2, ...在无限循环中得到等等。从Python 1.5.1开始,解释器会检测到此情况,
[1, 2,[...]]而是打印出来。


![省略号列表[…]并将列表与其自身连接 省略号列表[…]并将列表与其自身连接](http://www.mshxw.com/aiimages/31/638299.png)
