由于缺少一个更好的名字,我想在Python中做一个“izip_sorted”。函数的输入是许多可迭代的,每个都是有序的。输出是具有有序输出的单个可迭代。
print([x for x in izip_sorted([0,4,8], [1,3,5], [12,12,42],[])])
编辑:这是一个简单的例子。实际使用将是大约40个输入迭代,每个迭代有大约100000个元素。每个元素都是一个存储dict的类,并实现__cmp__
,以便对元素进行排序。数据太大,无法一次性读取。
应该打印
[0, 1, 3, 4, 5, 8, 12, 12, 42]
我有一个解决方案,但我是python的新手,我不知道它是非常 Pythonic 。这可以改进吗?只有1个元素发生变化的排序似乎很浪费......
def izip_sorted(*iterables):
"""
Return an iterator that outputs the values from the iterables, in sort order
izip_sort('ABF', 'D', 'CE') --> A B C D E F
"""
iterators = [iter(it) for it in iterables]
current_iterators = []
for it in iterators:
try:
current_iterators.append((next(it), it))
except StopIteration:
pass
current_iterators.sort(key=lambda x: x[0])
while(current_iterators):
yield current_iterators[0][0]
try:
current_iterators[0] = (next(current_iterators[0][1]), current_iterators[0][1])
current_iterators.sort(key=lambda x: x[0])
except StopIteration:
current_iterators = current_iterators[1:]
答案 0 :(得分:4)
我认为你要找的是链接迭代的所有值,然后对它们进行排序。为此,我们可以简单地合并itertools.chain()
和the sorted()
builtin:
>>> from itertools import chain
>>> sorted(chain([0,4,8], [1,3,5], [12,12,42],[]))
[0, 1, 3, 4, 5, 8, 12, 12, 42]
如果你有一个可迭代的列表,你可能想要使用itertools.chain.from_iterable()
。
>>> iterables = [[0,4,8], [1,3,5], [12,12,42],[]]
>>> sorted(chain.from_iterable(iterables))
[0, 1, 3, 4, 5, 8, 12, 12, 42]
编辑:对于您确切的问题,如果您知道输入列表已排序,并且每个输入列表的最后一项不会大于下一个列表的第一项,我们只需根据第一个值进行排序(使用sorted()
的关键功能)然后链接它们。
>>> from operator import itemgetter
>>> iterables = [[0,4,8], [1,3,5], [12,12,42]]
>>> sorted(iterables, key=itemgetter(0))
[[0, 4, 8], [1, 3, 5], [12, 12, 42]]
>>> list(chain.from_iterable(sorted(iterables, key=itemgetter(0))))
[0, 4, 8, 1, 3, 5, 12, 12, 42]
问题是,您提供给我们的数据不符合这些规则,因此答案不正确。
答案 1 :(得分:3)
如果输入没有排序,则必须全部实现(实际上,从可迭代变为列表)。如果不查看数据,就无法排序。 LattyWare's solution是最蟒蛇的。
另一方面,如果已知输入的可迭代内容已排序,则可以使用heapq.merge:
>>> from heapq import merge
>>> merge(*iterables)
答案 2 :(得分:2)
这不是zip
。 zip
将几个iterables拉成可迭代的元组。你的功能很简单:
sorted(itertools.chain(*iterables))
答案 3 :(得分:0)
您也可以这样做:
sorted([item for iterable in iterables for item in iterable])