Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么将这些对象(来自生成器)添加到列表时会发生更改?_Python - Fatal编程技术网

Python 为什么将这些对象(来自生成器)添加到列表时会发生更改?

Python 为什么将这些对象(来自生成器)添加到列表时会发生更改?,python,Python,所以我试图从生成器中获取对象,并将它们添加到列表中。但当我将它们添加到列表中时,列表中会填充空对象,而不是我添加的对象。为什么呢 此代码 #!/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.No

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

此代码

#!/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(节点)
打印相同的内容

这意味着生成器每次都返回相同的对象,并在调用之间对其进行变异。列表中的“对象”都是相同的对象,其状态反映了
节点()
实现在封面下所做的任何内部操作

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


我会向软件包作者抱怨这种行为。它充其量也很容易混淆和出错:-(

尝试在第二个循环中添加
打印id(节点)
。我怀疑(但不知道)节点()iterator每次都返回相同的对象。如果打印的所有ID都是相同的,那么肯定是相同的。是的。这会解释很多。我想知道为什么会这样。谢谢您的帮助!