gpt4 book ai didi

python - 为什么这些对象(来自生成器)在我将它们添加到列表时会发生变化?

转载 作者:行者123 更新时间:2023-11-28 16:41:24 25 4
gpt4 key购买 nike

所以我试图从生成器中获取对象并将它们添加到列表中。但是当我将它们添加到列表中时,列表中填充的是空对象,而不是我添加的对象。这是为什么?

这段代码

#!/usr/bin/python

# Create a graph with 5 nodes
from snap import *

G = TUNGraph.New()

for i in range(5):
G.AddNode(i)

# Ids of these nodes are 0, 1, 2, 3, 4
for node in G.Nodes(): # G.Nodes() is a generator
print node.GetId()

lst = []
for node in G.Nodes():
lst.append(node)

print
# All of the nodes magically change to have ID -1
print [node.GetId() for node in lst]

print
# The nodes in the original graph are unchanged
for i in G.Nodes():
print i.GetId()

产生输出

0
1
2
3
4

[-1, -1, -1, -1, -1]

0
1
2
3
4

最佳答案

好的!在对原件的评论中,我们确定

for node in G.Nodes():  # G.Nodes() is a generator
print node.GetId()
print id(node) # NEW LINE HERE

每次都为 id(node) 打印相同的内容。

这意味着生成器每次都返回相同的对象,并在调用之间改变它。列表中的“对象”都是同一个对象,它的状态反射(reflect)了 Nodes() 实现在幕后所做的任何内部摆弄。

我认为这是一个糟糕的设计,虽然我没有使用过 SNAP 所以不能确定。这是我经常看到的微效率技巧。当 CPython 在内部执行类似的操作时,它首先检查生成的对象上的引用计数是否为 1。当且仅当它为 1 时,CPython 知道它持有对生成的对象的唯一引用对象,所以改变它是安全的。但是,如果引用计数大于 1,CPython 会创建一个新对象以产生(因为用户可能会持有最后一个产生的对象 - 正如@eeeeeeeeee 在他的示例代码中所做的那样)。

我会向软件包作者投诉这种行为。它充其量是令人困惑和容易出错的:-(

关于python - 为什么这些对象(来自生成器)在我将它们添加到列表时会发生变化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18861321/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com