问题
So I came across something very weird in python. I tried adding a reference to the list to itself. The code might help demonstrate what I am saying better than I can express. I am using IDLE editor(interactive mode).
>>>l=[1,2,3]
>>>l.append(l)
>>>print(l)
[1,2,3,[...]]
>>>del l[:-1]
>>>print(l)
[[...]]
So far the output is as expected. But when I do this.
y=l[:]
print(y)
To me it seems that the output should be
[[...]]
But it is
[[[...]]]
Apparently instead of creating a copy of the list, it puts a reference to the list in y.
y[0] is l returns True. I can't seem to find a good explanation for this. Any ideas?
回答1:
The difference is only in the way the list is displayed. I.e. the value of y
is exactly what you'd expect.
The difference in the way the lists are displayed results from the fact that, unlike l
, y
is not a self-referencing list:
l[0] is l
=> True
y[0] is y
=> False
y
is not self-referencing, because y
does not reference y
. It references l
, which is self-referencing.
Therefor, the logic which translates the list to a string detects the potential infinite-recursion one level deeper when working on y
, than on l
.
回答2:
This is perfectly expected. When Python prints recursive lists, it checks that the list it is printing hasn't yet been encountered and if it has prints [...]
. An important point to understand is that it doesn't test for equality (as in ==
) but for identity (as in is
). Therefore,
when you print
l = [l]
. You havel[0] is l
returnsTrue
and therefore it prints[[...]]
.now
y = l[:]
makes a copy ofl
and thereforey is l
returnsFalse
. So here is what happens. It starts printingy
so it prints [ ??? ] where???
is replaced by the printing ofy[0]
. Nowy[0]
isl
and is noty
. So it prints[[???]]
with???
replaced byy[0][0]
. Nowy[0][0]
isl
which has already been encountered. So it prints[...]
for it giving finally[[[...]]]
.
回答3:
You need to have a full copy of the objects. You need to use copy.deepcopy and you would see the expected results.
>>> from copy import deepcopy
>>> l=[1,2,3]
>>> l.append(l)
>>> print(l)
[1, 2, 3, [...]]
>>> del l[:-1]
>>> print(l)
[[...]]
>>> y=deepcopy(l)
>>> print(y)
[[...]]
>>> y[0] is l
False
>>>
When you use the slice notation to copy the list, the inner references are retained which cause the behavior that you observe.
回答4:
Slicing generates list of items. There is only one item - list "l". So, we have new list of one element - list "l".
来源:https://stackoverflow.com/questions/21798483/recursive-reference-to-a-list-within-itself