Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/flutter/9.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 为什么';t在构造此defaultdict的每个循环中返回单个值?_Python_Yield_Defaultdict - Fatal编程技术网

Python 为什么';t在构造此defaultdict的每个循环中返回单个值?

Python 为什么';t在构造此defaultdict的每个循环中返回单个值?,python,yield,defaultdict,Python,Yield,Defaultdict,这是原始代码: 从集合导入defaultdict lis=[[1,2]、[2,1]、[3,0]、[2,1]、[1,1]] res=defaultdict(int) 对于lis中的i,j: res[i]+=j 打印(res.items()) 结果 dict_items([(1, 2)]) dict_items([(1, 2), (2, 1)]) dict_items([(1, 2), (2, 1), (3, 0)]) dict_items([(1, 2), (2, 2), (3, 0)]) di

这是原始代码:

从集合导入defaultdict
lis=[[1,2]、[2,1]、[3,0]、[2,1]、[1,1]]
res=defaultdict(int)
对于lis中的i,j:
res[i]+=j
打印(res.items())
结果

dict_items([(1, 2)])
dict_items([(1, 2), (2, 1)])
dict_items([(1, 2), (2, 1), (3, 0)])
dict_items([(1, 2), (2, 2), (3, 0)])
dict_items([(1, 3), (2, 2), (3, 0)])
我想使用
yield
获得这些打印项目

从集合导入defaultdict
li=[[1,2],[2,1],[3,0],[2,1],[1,1]]
def g(lis:列表):
res=defaultdict(int)
对于lis中的i,j:
res[i]+=j
收益率资源项目()
打印(*g(li))
但我明白了

dict_items([(1, 3), (2, 2), (3, 0)]) dict_items([(1, 3), (2, 2), (3, 0)]) dict_items([(1, 3), (2, 2), (3, 0)]) dict_items([(1, 3), (2, 2), (3, 0)]) dict_items([(1, 3), (2, 2), (3, 0)])

我发现了问题所在

因为
defaultdict
是一个可变对象

所以我需要复制
res
(不需要深度复制,因为项目是元组,不可更改)

或者直接返回
.items()


,使用
list()
新建对象

def g(lis:list):
res=defaultdict(int)
对于lis中的i,j:
res[i]+=j
产量列表(资源项())

您在自己的答案中所说的是正确的。我只是想确保您理解,如果您将每个值收集到一个列表中,然后使用一条
print
语句打印该列表,那么您发现的这个事实对于您的第一个代码示例同样适用<代码>收益率与您看到的问题无关。我希望您已经知道这一点,但我想指出一点,以防稍后阅读本文的人认为这是使用
yield
引入的问题。事实并非如此

要看到这一点,您可以更改第二个示例以立即打印生成的值。这样,您在两个示例中都在做相同的事情……生成下一个值后立即打印它。如果这样做,两个版本的代码都会得到相同的结果

下面是一整套代码来演示这一点:

from collections import defaultdict

lis = [[1, 2], [2, 1], [3, 0], [2, 1], [1, 1]]

res = defaultdict(int)
for i, j in lis:
    res[i] += j
    print(res.items())

def g(lis: list):
    res = defaultdict(int)
    for i, j in lis:
        res[i] += j
        yield res.items()

for v in g(lis):
    # Print the next generated value
    print(v)
结果:

dict_items([(1, 2)])
dict_items([(1, 2), (2, 1)])
dict_items([(1, 2), (2, 1), (3, 0)])
dict_items([(1, 2), (2, 2), (3, 0)])
dict_items([(1, 3), (2, 2), (3, 0)])
dict_items([(1, 2)])
dict_items([(1, 2), (2, 1)])
dict_items([(1, 2), (2, 1), (3, 0)])
dict_items([(1, 2), (2, 2), (3, 0)])
dict_items([(1, 3), (2, 2), (3, 0)])

让我们确认一下这段代码的意图:它想要创建整型键和整数值的dict。defaultdict功能从未实际使用过,例如,它不会创建与该键对应的所有整数值的列表,因此,例如,第5个条目1:1覆盖了1:2。这真的是你的意图吗?
from collections import defaultdict

lis = [[1, 2], [2, 1], [3, 0], [2, 1], [1, 1]]

res = defaultdict(int)
for i, j in lis:
    res[i] += j
    print(res.items())

def g(lis: list):
    res = defaultdict(int)
    for i, j in lis:
        res[i] += j
        yield res.items()

for v in g(lis):
    # Print the next generated value
    print(v)
dict_items([(1, 2)])
dict_items([(1, 2), (2, 1)])
dict_items([(1, 2), (2, 1), (3, 0)])
dict_items([(1, 2), (2, 2), (3, 0)])
dict_items([(1, 3), (2, 2), (3, 0)])
dict_items([(1, 2)])
dict_items([(1, 2), (2, 1)])
dict_items([(1, 2), (2, 1), (3, 0)])
dict_items([(1, 2), (2, 2), (3, 0)])
dict_items([(1, 3), (2, 2), (3, 0)])