省略号列表,并将其串联起来 [英] Ellipsis lists [...] and concatenating a list to itself

查看:82
本文介绍了省略号列表,并将其串联起来的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑:我在原始示例中很粗心.当我向自身添加列表A时,不会发生此行为,而是当我向A自身添加包含列表的列表时,发生这种情况.请参阅下面的更正示例.

I was careless in my original examples. The behaviour occurs not when I add list A to itself, but rather when I add a list containing list A to A itself. Please see the corrected examples below.

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

I am trying to understand how ellipsis lists (those lists that appear as [...] and occur when you have a list references itself) works in Python 2.

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

In particular, I want to know why, if A is a list, A = A + A seems to work differently to A += A (and A.append(A)).

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

That is, why do you get:

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

vs.

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

(请注意,a.append(a)似乎和后者一样对我有用.)

(Note that a.append(a) seems to work for me just as the latter did.)

有关此省略号列表现象的任何其他更一般的信息,如果有助于澄清问题,也将不胜感激.

Any additional more general information regarding this ellipsis list phenomenon would also be much appreciated if it helps to clarify things.

推荐答案

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

(to address the additional issues raised by your edits to the question):

a = a + ba += b是不同的操作.前者执行a.__add__(b),后者执行a.__iadd__(b)(就地添加").

a = a + b and a += b are not the same operation. The former executes a.__add__(b), the latter executes a.__iadd__(b) ("in-place add").

两者之间的区别在于,前者总是创建一个新对象(并将名称a重新绑定到该新对象),而后者则就地修改该对象(如果可以的话,并使用列表对其进行修改).可以).

The difference between the two is that the former always creates a new object (and rebinds the name a to that new object) while the latter modifies the object in-place (if it can, and with a list, it can).

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

To illustrate this, just look at the addresses of your objects:

>>> a = [1, 2]
>>> id(a)
34660104
>>> a = a + [a]
>>> id(a)
34657224
>>> id(a[2])
34660104

新" a是从头开始构建的,首先从旧列表a中获取值,然后将对旧对象的引用连接到该列表.

The "new" a was constructed from scratch, first taking the values from the old list a, then concatenating the reference to the old object to it.

将此与:

>>> a = [1, 2]
>>> id(a)
34658632
>>> a += [a]
>>> id(a)
34658632
>>> id(a[2])
34658632


(旧答案,解释循环引用):


(Old answer, explaining cyclic references):

考虑一下:

>>> 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, [...]]

因此,总结一下第一部分:

So, to summarize the first part:

对于列表,a += a等效于调用a.extend(a),后者会就地修改a,并在此操作开始时添加在a中找到的元素的副本.

For lists, a += a is equivalent to calling a.extend(a) which modifies a in-place, adding copies of the elements found in a at the start of this operation.

相反,a += [a]对应于a.append(a),两者均创建对列表a的引用(即,指向其在内存中地址的指针),并将 that 添加到列表中.构成所谓的循环参考".

Conversely, a += [a] corresponds to a.append(a), both of which create a reference to the list a (i. e. a pointer to its address in memory) and add that to the list. Which constitutes a so-called "cyclic reference".

如果此时要查看a的内部表示,它将看起来像这样:

If you were to look at the internal representation of a at that point, it would look something like this:

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之前的版本)不够聪明,无法检测到它,因此,如果执行print a,则会无限循环获得[1, 2, [1, 2, [1, 2, [1, 2, [1, 2, [1, 2, ...等.从Python 1.5.1开始,解释器会检测到此情况,而是打印[1, 2, [...]].

Old Python versions (pre-1.5.1) were not smart enough to detect that, so if you were to do a print a, you'd get [1, 2, [1, 2, [1, 2, [1, 2, [1, 2, [1, 2, ... etc. in an infinite loop. Since Python 1.5.1, the interpreter detects this, printing [1, 2, [...]] instead.

这篇关于省略号列表,并将其串联起来的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆