admin管理员组

文章数量:1122826

I'm trying to understand and/or name something.

Here is the code:

nums1 = [1, 2, 3]
nums2 = [1, 2, 3]
nums1.append(nums2)
print(nums1)
print(nums1[2])
print(nums1[3])
print("----")

nums = [1, 2, 3]
nums.append(nums)
print(nums)
print(nums[2])
print(nums[3])

When executed I get the following output:

[1, 2, 3, [1, 2, 3]]
3
[1, 2, 3]
----
[1, 2, 3, [...]]
3
[1, 2, 3, [...]]

The first section is normal append and makes sense.

The second section has the [...] which is telling me that the 3rd element is a self reference, which would definitely be "complex". What I'm unclear about is the last printed line. Why was the total list printed here, instead of "[...]"?

I was expecting the following output:

[1, 2, 3, [1, 2, 3]]
3
[1, 2, 3]
----
[1, 2, 3, [...]]
3
[...]

I'm trying to understand and/or name something.

Here is the code:

nums1 = [1, 2, 3]
nums2 = [1, 2, 3]
nums1.append(nums2)
print(nums1)
print(nums1[2])
print(nums1[3])
print("----")

nums = [1, 2, 3]
nums.append(nums)
print(nums)
print(nums[2])
print(nums[3])

When executed I get the following output:

[1, 2, 3, [1, 2, 3]]
3
[1, 2, 3]
----
[1, 2, 3, [...]]
3
[1, 2, 3, [...]]

The first section is normal append and makes sense.

The second section has the [...] which is telling me that the 3rd element is a self reference, which would definitely be "complex". What I'm unclear about is the last printed line. Why was the total list printed here, instead of "[...]"?

I was expecting the following output:

[1, 2, 3, [1, 2, 3]]
3
[1, 2, 3]
----
[1, 2, 3, [...]]
3
[...]
Share Improve this question edited Nov 21, 2024 at 19:11 John Kugelman 361k69 gold badges546 silver badges591 bronze badges asked Nov 21, 2024 at 19:06 Galen BoyerGalen Boyer 191 bronze badge 1
  • Which one is your actual question? Is it How to print a self-referencing cell in a list? or is it Why was the total list printed here, instead of "[...]"?? Title and body shouldn't disagree. – no comment Commented Nov 22, 2024 at 13:12
Add a comment  | 

1 Answer 1

Reset to default 5

The name nums and the expression nums[3] refer to the exact same object:

>>> nums is nums[3]
True

so it stands to reason there should be no difference in what nums.__repr__ and nums[3].__repr__ return. The method doesn't care where the reference to the object came from.

Put another way, if I gave you a variable y and you observed that y is nums is true, there is no way you could determine from the list itself whether I had originally defined y with

y = nums
y = nums[3]
y = nums[3][3]
y = nums[3][3][3]
# etc

There are only 4 unique objects here: 1, 2, 3, and the list. There is no nested list, only a list that contains a reference to itself in addition to references to 1, 2, and 3.


But list.__repr__ calls repr on all its elements. The [...] and the [1, 2, 3, [...]] output are both produced by calling repr on the exact same list. So why does the same call produce different output at different times?

The answer is that list.__repr__ detects recursive calls. If a call to the same list's __repr__ method is already on the call stack, list.__repr__ just returns '[...]'. This allows it to safely avoid infinite recursion, even in more complex situations than just a list containing a reference to itself.

You can achieve similar functionality with reprlib.recursive_repr, though list.__repr__ uses a separate, C-level implementation of similar functionality.

Here's what a pure-Python implementation of list.__repr__ might look like:

import reprlib

class list:
    ...

    @reprlib.recursive_repr('[...]')
    def __repr__(self):
        return f'[{", ".join(map(repr, self))}]'

本文标签: pythonHow to print a selfreferencing cell in a listStack Overflow