【发布时间】:2019-05-04 20:51:33
【问题描述】:
我正在尝试编写一个函数来基于列表构建一个扁平的生成器树。所以如果我有一个项目列表,我想从一个空生成器开始,并在第一个项目和空生成器上调用一个函数,然后在第二个项目上调用函数和第一个函数调用的输出,然后调用第三个项目的函数和第二个函数调用的输出,依此类推。 重要的是,在最终生成器上调用 next 之前,我不想真正评估 任何东西!
所以,如果我们在列表和生成器上调用的函数被称为foo,(显然它也输出一个生成器),并且项目列表是list...
现在,我有一个原型,如下所示:
>>> tree = iter([{}])
>>> tree = chain.from_iterable((foo(list[0], p) for p in tree))
>>> tree = chain.from_iterable((foo(list[1], p) for p in tree))
>>> tree = chain.from_iterable((foo(list[2], p) for p in tree))
>>> list(tree)
这确实有效。它会正确评估所有内容,最重要的是不会不必要地评估任何内容(以整数开头的行是在实际情况下打印的日志:
>>> next(tree)
Called on 0
Called on 1
Called on 2
Result A
>>> next(tree)
Called on 1
Called on 2
Result B
不幸的是,当我尝试使用循环使其在任意长度的 tail 上工作时:
tree = iter([{}])
for item in list:
tree = chain.from_iterable((foo(item, p) for p in tree))
它不起作用。相反,tree 变量设置为在 empty 可能性上调用 foo 的结果,就好像它是唯一被评估的东西一样!我不知道发生了什么,虽然我有一个 预感 那是因为有一个指针什么的。
任何帮助将不胜感激!
【问题讨论】:
-
是的,这似乎是相关的......如果由此推测 Python 中的生成器表达式不会将其范围保存在表达式的正确部分,它们会在执行时使用变量.不过,我不确定如何解决这个问题,特别是因为保存中间
trees 不起作用。
标签: python pointers iterator generator