嵌套在理解中的生成器的意外行为
Unexpected behaviour of generator nested in a comprehension
当使用嵌套在推导中的生成器时,我在 Python 中出现意外行为,在下面的特定情况下是字典推导。更具体地说,考虑以下简单的理解:
D = {x : (y for y in range(5) if y==x) for x in range(5)}
我本希望得到一个字典 D
使得每个整数 i 从 0 到 4 都 list(D[x]) == [x]
。相反,结果是
>>> list(D[0])
[4]
>>> list(D[1])
[4]
>>> list(D[2])
[4]
>>> list(D[3])
[4]
>>> list(D[4])
[4]
我认为发生这种情况是因为用于定义生成器的变量 x
的值一直在变化 until 被固定为 4。但是,我认为每个生成器都应该使用确切的值来定义定义时的变量。对于这个简单的嵌套结构,是否有替代方法以更正的方式并达到预期的结果?
请注意,将生成器实现为列表会修复此行为:
D = {x : list((y for y in range(5) if y==x)) for x in range(5)}
但我对保留发电机使用的解决方案很感兴趣。
x
是一个自由变量,因此在您实际迭代生成器之前不会考虑它的值。正如您所注意到的,这意味着 x
的值可以在生成器定义和实际使用之间发生变化。
无法将值传递给生成器表达式;你必须使用生成器函数:
def make_generator(x):
for y in range(5):
if y == x:
yield y
D = {x: make_generator(x) for x in range(5)}
对于你所描述的场景(我不明白你为什么需要内悟),你可以简单地使用以下内容:
d = {x:lambda x: [x] for x in range(5)}
print(d[3](3))
这将给出:
[3]
当使用嵌套在推导中的生成器时,我在 Python 中出现意外行为,在下面的特定情况下是字典推导。更具体地说,考虑以下简单的理解:
D = {x : (y for y in range(5) if y==x) for x in range(5)}
我本希望得到一个字典 D
使得每个整数 i 从 0 到 4 都 list(D[x]) == [x]
。相反,结果是
>>> list(D[0])
[4]
>>> list(D[1])
[4]
>>> list(D[2])
[4]
>>> list(D[3])
[4]
>>> list(D[4])
[4]
我认为发生这种情况是因为用于定义生成器的变量 x
的值一直在变化 until 被固定为 4。但是,我认为每个生成器都应该使用确切的值来定义定义时的变量。对于这个简单的嵌套结构,是否有替代方法以更正的方式并达到预期的结果?
请注意,将生成器实现为列表会修复此行为:
D = {x : list((y for y in range(5) if y==x)) for x in range(5)}
但我对保留发电机使用的解决方案很感兴趣。
x
是一个自由变量,因此在您实际迭代生成器之前不会考虑它的值。正如您所注意到的,这意味着 x
的值可以在生成器定义和实际使用之间发生变化。
无法将值传递给生成器表达式;你必须使用生成器函数:
def make_generator(x):
for y in range(5):
if y == x:
yield y
D = {x: make_generator(x) for x in range(5)}
对于你所描述的场景(我不明白你为什么需要内悟),你可以简单地使用以下内容:
d = {x:lambda x: [x] for x in range(5)}
print(d[3](3))
这将给出:
[3]