生成器合并排序的字典类似的迭代

时间:2014-09-11 03:48:37

标签: python sorting dictionary iterator python-2.6

这是Generator to yield gap tuples from zipped iterables的变体。

我希望设计一个生成器函数:

  • 接受任意数量的iterables
  • 每个输入可迭代产生零个或多个(k,v),k不一定是唯一的
  • 假设输入键按升序排序
  • 输出应该产生(k, (v1, v2, ...))
  • 输出键 唯一,并以与输入
  • 相同的顺序显示
  • 输出元组的数量等于输入
  • 中唯一键的数量
  • 输出值对应于与输出键匹配的所有输入元组
  • 由于输入和输出可能很大,因此应将它们视为可迭代,而不是作为内存中的字典或列表加载。

举个例子,

i1 = ((2, 'a'), (3, 'b'), (5, 'c'))
i2 = ((1, 'd'), (2, 'e'), (3, 'f'))
i3 = ((1, 'g'), (3, 'h'), (5, 'i'), (5, 'j'))
result = sorted_merge(i1, i2, i3)
print [result]

这将输出:

[(1, ('d', 'g')), (2, ('a', 'e')), (3, ('b', 'f', 'h')), (5, ('c', 'i', 'j'))]

如果我没有弄错的话,Python标准库中没有任何内置功能来开箱即用。

2 个答案:

答案 0 :(得分:3)

虽然没有一个标准库函数可以执行您想要的操作,但enough building blocks可以帮助您完成所有工作:

from heapq import merge
from itertools import groupby
from operator import itemgetter

def sorted_merge(*iterables):
    for key, group in groupby(merge(*iterables), itemgetter(0)):
        yield key, [pair[1] for pair in group]    

示例:

>>> i1 = ((2, 'a'), (3, 'b'), (5, 'c'))
>>> i2 = ((1, 'd'), (2, 'e'), (3, 'f'))
>>> i3 = ((1, 'g'), (3, 'h'), (5, 'i'), (5, 'j'))
>>> result = sorted_merge(i1, i2, i3)
>>> list(result)
[(1, ['d', 'g']), (2, ['a', 'e']), (3, ['b', 'f', 'h']), (5, ['c', 'i', 'j'])]

请注意,在上面的sorted_merge版本中,我们为了产生可读输出而产生intlist对。没有什么可以阻止你将相关的行改为

        yield key, (pair[1] for pair in group)          

如果您想要产生int<generator>对。

答案 1 :(得分:0)

有点不同:

from collections import defaultdict

def sorted_merged(*items):
    result = defaultdict(list)
    for t in items:
        for k, v in t:
           result[k].append(v)
    return sorted(list(result.items()))

i1 = ((2, 'a'), (3, 'b'), (5, 'c'))
i2 = ((1, 'd'), (2, 'e'), (3, 'f'))
i3 = ((1, 'g'), (3, 'h'), (5, 'i'), (5, 'j'))

result = sorted_merged(i1, i2, i3)