Ellipsis Lists [...] And Concatenating A List To Itself
Solution 1:
Edit: (to address the additional issues raised by your edits to the question):
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").
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
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.
Contrast this to:
>>>a = [1, 2]>>>id(a)
34658632
>>>a += [a]>>>id(a)
34658632
>>>id(a[2])
34658632
(Old answer, explaining cyclic references):
Consider this:
>>>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:
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.
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".
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 integerobject"1"
a[1]: Reference to the integerobject"2"
a[2]: Reference to the same list object at address 0xDEADBEEF
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.
Solution 2:
Consider the following:
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
Notice first of all that +=
does not create an ellipsis list.
Secondly, it can be seen that the ellipsis-list indicates that accesing that slot will return the exact same list - the ellipsis-list represents a pointer to the outer list (or, almost certainly an outer list if there is more than one level of nesting).
Solution 3:
This is because a = a + a
corresponds to a.extend(a)
which "Extend the list by appending all the items in the given list". Another way to look at it is that the +
operator results in "the concatenation of s and t".
This is in contrast to a += a
which corresponds to a.append(a)
which "adds an item at the end of the list".
Hope that clarifies things.
Post a Comment for "Ellipsis Lists [...] And Concatenating A List To Itself"