Python 省略号列表[…]并将列表连接到自身

Python 省略号列表[…]并将列表连接到自身,python,list,concatenation,Python,List,Concatenation,编辑:我在最初的示例中很粗心。这种行为不是在我将列表A添加到自身时发生的,而是在我将包含列表A的列表添加到A自身时发生的。请参阅下面更正的示例 我试图理解省略号列表(那些显示为[…]并且在列表引用自身时出现的列表)在Python 2中是如何工作的 特别是,我想知道为什么,如果A是列表,A=A+A似乎与A+=A(和A.append(A))的工作方式不同 也就是说,你为什么会得到: >>> a = [1, 2] >>> a = a + [a] >>

编辑:我在最初的示例中很粗心。这种行为不是在我将列表
A
添加到自身时发生的,而是在我将包含列表
A
的列表添加到
A
自身时发生的。请参阅下面更正的示例


我试图理解省略号列表(那些显示为
[…]
并且在列表引用自身时出现的列表)在Python 2中是如何工作的

特别是,我想知道为什么,如果
A
列表
A=A+A
似乎与
A+=A
(和
A.append(A)
)的工作方式不同

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

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

(注意,
a.append(a)
似乎和后者一样适用于我。)


如果有助于澄清问题,我们也将非常感谢有关省略号列表现象的任何其他更一般的信息。

考虑以下几点:

In [179]: a = [1, 2]

In [180]: a+=a

In [181]: a
Out[181]: [1, 2, 1, 2]

In [182]: a.append(a)

In [183]: a
Out[183]: [1, 2, 1, 2, [...]]

In [184]: a[5]
-----------------------------------------------
IndexError                                Trace
C:\Users\Marcin\Documents\oneclickcos\oneclickc
----> 1 a[5]

IndexError: list index out of range

In [185]: a[4]
Out[185]: [1, 2, 1, 2, [...]]

In [186]: a[3]
Out[186]: 2

In [187]: a[4]
Out[187]: [1, 2, 1, 2, [...]]

In [188]: a
Out[188]: [1, 2, 1, 2, [...]]

In [189]: a[4][3]
Out[189]: 2

In [190]: a[4][4]
Out[190]: [1, 2, 1, 2, [...]]

In [191]: a[4][5]
-----------------------------------------------
IndexError                                Trace
C:\Users\Marcin\Documents\oneclickcos\oneclickc
----> 1 a[4][5]

IndexError: list index out of range

In [192]: a[4][4]
Out[192]: [1, 2, 1, 2, [...]]

In [193]: a = [1, 2]

In [194]: a+=a

In [195]: a
Out[195]: [1, 2, 1, 2]

In [196]: a
Out[196]: [1, 2, 1, 2]

In [197]: a
Out[197]: [1, 2, 1, 2]

In [198]: a.append(a)

In [200]: a
Out[200]: [1, 2, 1, 2, [...]]

In [201]: a.append(a)

In [202]: a
Out[202]: [1, 2, 1, 2, [...], [...]]

In [203]: a[4]
Out[203]: [1, 2, 1, 2, [...], [...]]

In [204]: a[5]
Out[204]: [1, 2, 1, 2, [...], [...]]

In [205]: id(a)
Out[205]: 64692680L

In [206]: id(a[5])
Out[206]: 64692680L

In [207]: id(a[4])
Out[207]: 64692680L

In [208]: id(a) == id(a[4]) and id(a[4]) == id(a[5])
Out[208]: True
首先请注意,
+=
不会创建省略号列表

其次,可以看到省略号列表表示访问该插槽将返回完全相同的列表-省略号列表表示指向外部列表的指针(或者,如果存在多个嵌套级别,则几乎肯定是外部列表)。

编辑:(为了解决您对问题的编辑提出的其他问题):

a=a+b
a+=b
是不同的操作。前者执行
a.\uu添加(b)
,后者执行
a.\uu添加(b)
(“就地添加”)

两者之间的区别在于前者总是创建一个新对象(并将名称
a
重新绑定到该新对象),而后者则在适当的位置修改对象(如果可以,并且可以使用列表)

为了说明这一点,只需查看对象的地址:

>>> a = [1, 2]
>>> id(a)
34660104
>>> a = a + [a]
>>> id(a)
34657224
>>> id(a[2])
34660104
“new”
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之前)没有足够的智能来检测这一点,因此如果您要执行
打印
,您将在无限循环中得到
[1,2,1,2,1,2,1,2,1,2,2,1,2,2,1,2,
等。由于Python 1.5.1,解释器会检测到这一点,打印
[1,2,[…]
相反。

这是因为
a=a+a
对应于
a.extend(a)
,另一种方式是
+
操作符导致

这与
a+=a
相对应,后者对应于
a


希望这能澄清问题。

a=[1,2];a+=a
将使
[1,2,1,2]
,而不是
[1,2,1,2]
。请看重复的问题。所谓的重复根本不讨论省略号列表。我也不了解最接近的投票。指针的概念对python很重要,值得解释。
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