python - 添加到同一个字典的不同生成器返回相同的值

标签 python python-3.x dictionary python-itertools

我刚刚遇到了一个奇怪的 Python (3.7.0) 行为,我并不真正理解它,对我来说它看起来像是一个错误。我想用生成器创建一个字典,但不知何故它们都返回相同的值。这是我正在谈论的代码示例:

import itertools

d = {
"a": [-1, 2],
"b": [1, 2],
"c": [20, 20]
}
g = dict()
g2 = dict()
for letter, values in d.items():
    g[letter] = (values[0] * values[1] * x for x in itertools.count())
    g2[letter] = [values[0] * values[1] * x for x in range(3)]

for i in range(3):
    for l, v in g.items():
        print(v.__next__())
print(g2)

从我的角度来看,g2 元素和 g 生成器的预期输出是相同的,但是我总是从最新的生成器接收值:

0
0
0
400
400
400
800
800
800
{'a': [0, -2, -4], 'b': [0, 2, 4], 'c': [0, 400, 800]}

总而言之,我做错了什么吗?或者它只是标准的 Python 行为?

最佳答案

这个错误不是由生成器引起的。这是范围界定错误。

在您的生成器声明中,您使用名称 values,尽管生成器直到 after 循环完成后才执行,其中 values 是现在是列表中的最后一项。这是一个重现您的错误的示例。

for i in [1]:
    g = (i for _ in range(3))

i = 'some new value'

print(next(g)) # 'some new value'

换句话说,values[0]values[1] 没有绑定(bind)到生成器,如果名称 values 后面的值然后发电机输出也会发生变化。

这意味着您希望生成器周围有一个闭包来存储值 values[0]values[1]。您可以通过将生成器定义为函数来实现。

import itertools

# Here is a function taht will return a generator
def gen(a, b):
    for x in itertools.count():
        yield a * b * x

d = {"a": [-1, 2], "b": [1, 2], "c": [20, 20]}

g, g2 = dict(), dict()

for letter, values in d.items():
    g[letter] = gen(values[0], values[1])
    g2[letter] = [values[0] * values[1] * x for x in range(3)]

for i in range(3):
    for l, v in g.items():
        print(next(v))

print(g2)

事实上,由于这个原因,很少使用内联生成器。支持使用 def-yield 创建生成器的方式。

此外,不要调用 __next__,而是使用内置的 next

输出

0
0
0
-2
2
400
-4
4
800
{'a': [0, -2, -4], 'b': [0, 2, 4], 'c': [0, 400, 800]}

关于python - 添加到同一个字典的不同生成器返回相同的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52456187/

相关文章:

python - 需要在列表列表中找到最大值

python-3.x - Jupyter Lab 中的 ipyparallel 并行函数调用示例

python - 在 python 的 azure 函数中安装 google api 时出错

ios - 从可变数组或字典中设置按钮标题和操作?

c# - 订购字典

r - 如何使用 ggplot2 包在 map 上绘制不同颜色的经纬度点?

python - 如何解决 mtrand.RandomState.choice 中的内存错误?

python - 如何使用 numpy 以行和列形式将数据保存在 .csv 文件中

Python Requests 库在日志记录中抛出异常

python - 如何将 UPX 与 pyinstaller 一起使用?