防止迭代器受到定义中使用的变量更改的影响



编辑/解决方案

这里有一个更接近我实际问题的例子,以及jonrsharpe实现注释的解决方案。谢谢

import io
import heapq

# THIS DOES NOT WORK AS INTENDED
files = dict(f0=io.StringIO("first linensecond line"),
f1=io.StringIO("FIRST LINEnSECOND LINE"))
iterators = ((line.split() + [fname] for line in f)
for fname, f in files.items())
list(heapq.merge(*iterators))
# [['FIRST', 'LINE', 'f0'],
#  ['SECOND', 'LINE', 'f0'],
#  ['first', 'line', 'f0'],
#  ['second', 'line', 'f0']]
# THIS DOES WORK
files = dict(f0=io.StringIO("first linensecond line"),
f1=io.StringIO("FIRST LINEnSECOND LINE"))
iterators = ((lambda x=fname: ((line.split() + [x]) for line in f))(fname)
for fname, f in files.items())
list(heapq.merge(*iterators))
# [['FIRST', 'LINE', 'f1'],
#  ['SECOND', 'LINE', 'f1'],
#  ['first', 'line', 'f0'],
#  ['second', 'line', 'f0']]

原始问题

如何使下面的Python代码生成[(1, 0), (1, 1)]而不是[(2, 0), (2, 1)]?也就是说,我希望结果不受迭代器it定义后对const所做更改的影响。

>>> const = 1
>>> var = range(2)
>>> it = ((const, i) for i in var)
>>> const = 2
>>> list(it)
[(2, 0), (2, 1)]

我在现实世界中遇到的问题是,在不将所有内容保存在内存中的情况下,对多个文件进行堆合并。我想以编程方式生成迭代器,将文件名与每个文件的每一行一起报告,例如("file2.txt", "this is line 1")。目前,我所有的迭代器最终都报告了相同的文件名。

您可以将生成器表达式从模块范围移动到函数中,因此const值将从函数范围中读取,对const的进一步更改不会影响生成器表达式的评估:

def hide_gen(const):
return ((const, i) for i in [0, 1])
const = 1
it = hide_gen(const)
const = 2
print(list(it))
# [(1, 0), (1, 1)]

最新更新