这个问题在这里已有答案:
起源
答案:
区别仅在于列表的显示方式。即的价值 y
正是你所期待的。
列表显示方式的不同源于这样的事实,不同于 l
, y
不是自引用列表:
l[0] is l
=> True
y[0] is y
=> False
y
不是自我引用,因为 y
没有参考 y
。它引用了 l
,这是自我引用。
因此,将列表转换为字符串的逻辑在工作时会检测到更深层次的潜在无限递归 y
,而不是 l
。
这完全可以预料到。当Python打印递归列表时,它会检查它正在打印的列表是否尚未遇到以及是否有打印 [...]
。需要了解的一点是它不能测试 平等 (如 ==
) 但对于 身分 (如 is
)。因此,
当你打印
l = [l]
。你有l[0] is l
回报True
因此它打印[[...]]
。现在
y = l[:]
制作副本l
因此y is l
回报False
。所以这就是发生的事情。它开始打印y
所以它打印[??? ]哪里???
被印刷所取代y[0]
。现在y[0]
是l
而不是y
。所以它打印[[???]]
同???
取而代之y[0][0]
。现在y[0][0]
是l
已经遇到过。所以它打印[...]
因为它终于给予了[[[...]]]
。
答案:
区别仅在于列表的显示方式。即的价值 y
正是你所期待的。
列表显示方式的不同源于这样的事实,不同于 l
, y
不是自引用列表:
l[0] is l
=> True
y[0] is y
=> False
y
不是自我引用,因为 y
没有参考 y
。它引用了 l
,这是自我引用。
因此,将列表转换为字符串的逻辑在工作时会检测到更深层次的潜在无限递归 y
,而不是 l
。
这完全可以预料到。当Python打印递归列表时,它会检查它正在打印的列表是否尚未遇到以及是否有打印 [...]
。需要了解的一点是它不能测试 平等 (如 ==
) 但对于 身分 (如 is
)。因此,
当你打印
l = [l]
。你有l[0] is l
回报True
因此它打印[[...]]
。现在
y = l[:]
制作副本l
因此y is l
回报False
。所以这就是发生的事情。它开始打印y
所以它打印[??? ]哪里???
被印刷所取代y[0]
。现在y[0]
是l
而不是y
。所以它打印[[???]]
同???
取而代之y[0][0]
。现在y[0][0]
是l
已经遇到过。所以它打印[...]
因为它终于给予了[[[...]]]
。
你需要一个 完整副本 的对象。你需要使用 copy.deepcopy
你会看到预期的结果。
>>> 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
>>>
使用切片表示法复制列表时,将保留内部引用,这会导致您观察到的行为。
切片生成项目列表。只有一个项目 - 列表“l”。所以,我们有一个新元素列表 - 列表“l”。