1

より良い名前がないので、Pythonで「izip_sorted」を実行したいと思います。関数への入力は、それぞれがソートされた多数の反復可能オブジェクトです。出力は、ソートされた出力を持つ単一の反復可能です。

print([x for x in izip_sorted([0,4,8], [1,3,5], [12,12,42],[])])

編集:これは簡単な例です。実際の使用法は、それぞれ約100000個の要素を持つ約40個の入力反復可能オブジェクトです。__cmp__各要素は、要素を並べ替えることができるようにdictと実装を格納するクラスです。データが大きすぎて一度に読み込むことができません。

印刷する必要があります

[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:]
4

4 に答える 4

4

あなたが探しているのは、反復可能オブジェクトのすべての値を連鎖させてから、それらをソートすることだと思います。これを行うには、単純にと組み込みを組み合わせることitertools.chain()できますsorted()

>>> 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]

問題は、あなたが私たちに提供したデータがこれらの規則に従わないため、間違った答えであるということです。

于 2012-05-19T15:11:06.177 に答える
4

入力がソートされていない場合は、すべてを実現する必要があります(基本的に、反復可能からリストに変換されます)。データを見ずに並べ替えることはできません。 LattyWareのソリューションは最もPython的です。

一方、入力反復可能オブジェクトがソートされていることがわかっている場合は、heapq.mergeを使用できます。

>>> from heapq import merge
>>> merge(*iterables)
于 2012-05-19T15:29:50.880 に答える
2

これはではありませんzipzipいくつかの反復可能オブジェクトを反復可能な生成タプルに圧縮します。あなたの機能は単純です:

sorted(itertools.chain(*iterables))
于 2012-05-19T15:11:07.567 に答える
0

次のこともできます。

sorted([item for iterable in iterables for item in iterable])
于 2012-05-19T15:12:07.177 に答える