我有以下代码片段。
x = (w for w in words if len(w) == 5)
def mk_gen(x, idx, val):
return (w for w in x if w[idx] == val)
pattern = 'he_l_'
for idx, val in enumerate(pattern):
if val == '_':
continue
x = mk_gen(x, idx, val) # Method 1
# x = (w for w in x if w[idx] == val) # Method 2
print((list(x)))
# Method 1 -> ['heald', 'heals', 'heels', 'heild', 'heily', 'heils', 'helly', 'hello', 'hells', 'herls']
# Method 2 -> []
这里的单词是英语词典中的单词列表。
方法1给出了预期的输出。
然而,方法2并不这样做,尽管事实上方法1正在做与方法2相同的事情,但调用一个返回它的函数,而不是直接分配新的生成器。
为什么会发生这种情况?
我尝试了另一种方法来创建一个新的生成器,使用函数调用。
def mk_gen_1(x, idx, val):
for w in x:
if w[idx] == val:
yield w
这一个也工作,但原来的方法2不.
我在Pythonic way to chain python generator function to form a pipeline中找到的另一个不起作用。
gen_2_steps = [(lambda g:(w for w in g if w[idx] == val)) for idx, val in enumerate(pattern) if val != '_']
x = reduce(lambda g, f: f(g), [x, *gen_2_steps]) # Method 3
print(list(x))
这一个工作,但它不是我打算做的。我打算通过使用for循环创建生成器,而不调用另一个函数。
# Works
f2_1 = lambda g:(w for w in g if w[0] == 'h')
x = f2_1(x)
f2_2 = lambda g:(w for w in g if w[1] == 'e')
x = f2_2(x)
f2_3 = lambda g:(w for w in g if w[3] == 'l')
x = f2_3(x)
print(len(list(x)))
1条答案
按热度按时间pieyvz9o1#
方法1和方法2使用两组不同的变量。
方法1使用由
mk_gen
定义的本地名称idx
和val
;它基本上定义了一个闭包,其中传递给mk_gen
的值即使在mk_gen
返回之后也会被生成器记住。方法2使用由
for
循环定义(和重新定义)的名称idx
和val
,因为生成器表达式与这些变量处于同一作用域。