对自身内部列表的递归引用[重复]

Posted

技术标签:

【中文标题】对自身内部列表的递归引用[重复]【英文标题】:Recursive reference to a list within itself [duplicate] 【发布时间】:2014-03-14 22:37:51 【问题描述】:

所以我在 python 中遇到了一些非常奇怪的东西。我尝试将对列表的引用添加到自身。该代码可能有助于证明我所说的比我能表达的更好。我正在使用 IDLE 编辑器(交互模式)。

>>>l=[1,2,3]
>>>l.append(l)
>>>print(l)
[1,2,3,[...]]
>>>del l[:-1]
>>>print(l)
[[...]]

到目前为止,输出符合预期。但是当我这样做时。

y=l[:]
print(y)

在我看来,输出应该是

[[...]]

但它是

[[[...]]]

显然,它不是创建列表的副本,而是在 y 中放置对列表的引用。

y[0] is l 返回 True。我似乎找不到一个很好的解释。有什么想法吗?

【问题讨论】:

【参考方案1】:

您需要拥有对象的完整副本。您需要使用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
>>>

当您使用切片表示法复制列表时,会保留内部引用,这会导致您观察到的行为。

【讨论】:

【参考方案2】:

这是完全可以预料的。当 Python 打印递归列表时,它会检查它正在打印的列表是否尚未遇到,以及是否打印了 [...]。要理解的重要一点是,它不测试平等(如==),而是测试identity(如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 : [ ??? ]..... 如果我真的想要一份列表副本怎么办?我知道在这种情况下我可以对 y 做同样的事情,但是为了讨论,有没有办法可以做到? @Sabyasachi:这样更清楚吗? @Sabyasachi:第二个问题非常含糊。你说的是哪个清单?我觉得你应该想想深拷贝和浅拷贝的区别(见***.com/questions/184710/…) 是的,谢谢,它更清楚了。我说的是列表 l。反正我现在明白了。谢谢:)【参考方案3】:

切片生成项目列表。只有一项 - 列表“l”。所以,我们有一个元素的新列表 - 列表“l”。

【讨论】:

【参考方案4】:

区别仅在于列表的显示方式。 IE。 y 的值正是您所期望的。

列表显示方式的不同是因为与l 不同,y 不是自引用列表:

l[0] is l
=> True
y[0] is y
=> False

y 不是自引用的,因为 y 不引用 y。它引用了l,它是自引用的。

因此,将列表转换为字符串的逻辑在处理y 时检测到比l 更深一层的潜在无限递归。

【讨论】:

以上是关于对自身内部列表的递归引用[重复]的主要内容,如果未能解决你的问题,请参考以下文章

我可以使用 Ruby 从自身内部引用 lambda 吗?

引用计数 - 内部引用问题

函数如何在 JavaScript 中引用自身?

递归求和

Python 方法是不是可以检查它是不是已从自身内部调用?

是否可以在 PHP 中从自身内部引用匿名函数?