这是一个更贴切地模仿我的真实问题的示例,以及通过jonrsharpe实现评论的解决方案。谢谢!
import io
import heapq
# THIS DOES NOT WORK AS INTENDED
files = dict(f0=io.StringIO("first line\nsecond line"),
f1=io.StringIO("FIRST LINE\nSECOND 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 line\nsecond line"),
f1=io.StringIO("FIRST LINE\nSECOND 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)]
?也就是说,我希望结果不会受到在迭代器const
定义后对it
所做的更改的影响。
>>> const = 1
>>> var = range(2)
>>> it = ((const, i) for i in var)
>>> const = 2
>>> list(it)
[(2, 0), (2, 1)]
我的真实问题是heapq.merge多个文件,而不将所有内容保存在内存中。我想以编程方式生成迭代器,报告文件名以及每个文件的每一行,例如: ("file2.txt", "this is line 1")
。目前,我的所有迭代器最终都报告了相同的文件名。
答案 0 :(得分:0)
您可以将生成器表达式从模块范围移动到函数中,因此从函数范围读取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)]