【发布时间】:2018-08-27 11:32:58
【问题描述】:
我有多个产生键控数据的排序迭代器,可以用列表表示:
a = iter([(1, 'a'), (2, 't'), (4, 'c')])
b = iter([(1, 'a'), (3, 'g'), (4, 'g')])
我想合并它们,使用键并跟踪哪个迭代器具有键值。这应该相当于 SQL 中的完全外连接:
>>> list(full_outer_join(a, b, key=lambda x: x[0]))
[(1, 'a', 'a'), (2, 't', None), (3, None, 'g'), (4, 'c', 'g')]
我尝试使用 heapq.merge 和 itertools.groupby,但使用 merge 我已经丢失了有关迭代器的信息:
>>> list(heapq.merge(a, b, key=lambda x: x[0]))
[(1, 'a'), (1, 'a'), (2, 't'), (3, 'g'), (4, 'c'), (4, 'g')]
所以我可以使用标签生成器
def tagged(it, tag):
for item in it:
yield (tag, *x)
并合并标记的迭代器,按键分组并使用标记创建字典:
merged = merge(tagged(a, 'a'), tagged(b, 'b'), key=lambda x: x[1])
grouped = groupby(merged, key=lambda x: x[1])
[(key, {g[0]: g[2] for g in group}) for key, group in grouped]
这给了我这个可用的输出:
[(1, {'a': 'a', 'b': 'a'}),
(2, {'a': 't'}),
(3, {'b': 'g'}),
(4, {'a': 'c', 'b': 'g'})]
但是,我认为为每个组创建字典在性能方面非常昂贵,所以也许有更优雅的方法?
编辑:
为了澄清,数据集太大而无法放入内存,所以我肯定需要使用生成器/迭代器。
编辑 2:
为了进一步澄清,a 和 b 应该只迭代一次,因为它们代表读取速度很慢的大文件。
【问题讨论】:
-
您的问题解决了吗?随意发布您自己的解决方案,或者如果他们有帮助,请接受以下其中一项。
-
我有一个解决方案但我还没有实现它,我一有它就会发布它。干杯 =)
标签: python functional-programming iterator generator