小编典典

省略号列表[…]并将列表与其自身连接

python

编辑: 我在原始示例中粗心大意。该行为不是在我A向自身添加列表时发生的,而是在我向自身添加 包含
列表的列表时A发生的A。请参阅下面的更正示例。


我试图理解省略号列表(那些[...]在您具有列表引用本身时出现并出现的列表)在Python 2中的工作方式。

我特别想知道为什么,如果AlistA = A + A似乎不同的工作A += A(和A.append(A))。

也就是说,为什么会得到:

>>> a = [1, 2]  
>>> a = a + [a]
>>> a  
[1, 2, [1, 2]]

>>> a = [1, 2]  
>>> a += [a]
>>> a
[1, 2, [...]]

(请注意,这a.append(a)似乎对我很有效,就像后者一样。)

如果它有助于弄清楚事情,那么也将不胜感激有关此省略号列表现象的任何其他更一般的信息。


阅读 131

收藏
2020-12-20

共1个答案

小编典典

编辑:( 以解决您对问题的编辑引起的其他问题):

a = a + ba += 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 0xDEADBEEF
a[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, [...]]而是打印出来。

2020-12-20