27

私は2つのリストを一緒にソートしようとしています:

list1 = [1, 2, 5, 4, 4, 3, 6]
list2 = [3, 2, 1, 2, 1, 7, 8]

list1, list2 = (list(x) for x in zip(*sorted(zip(list1, list2))))

とにかく、これを行うと出力が得られます

list1 = [1, 2, 3, 4, 4, 5, 6]
list2 = [3, 2, 7, 1, 2, 1, 8]

最初のリストで同じ番号4の最初の順序を維持したいのですが、私が欲しいのは

list1 = [1, 2, 3, 4, 4, 5, 6]
list2 = [3, 2, 7, 2, 1, 1, 8]

私は何をしなければなりませんか?バブルソートにループを使いたくありません。助けていただければ幸いです。

4

3 に答える 3

35

keyペアの最初の要素のみを比較するソート用のパラメーターを使用します。Pythonの並べ替えは安定しているため、最初の要素が等しい場合でも、2番目の要素の順序は同じままであることが保証されます。

>>> from operator import itemgetter
>>> [list(x) for x in zip(*sorted(zip(list1, list2), key=itemgetter(0)))]
[[1, 2, 3, 4, 4, 5, 6], [3, 2, 7, 2, 1, 1, 8]]

これは次と同等です:

>>> [list(x) for x in zip(*sorted(zip(list1, list2), key=lambda pair: pair[0]))]
[[1, 2, 3, 4, 4, 5, 6], [3, 2, 7, 2, 1, 1, 8]]
于 2012-12-02T10:29:34.843 に答える
7

ここでの秘訣は、Pythonがタプル比較を行うときに、要素を左から右の順序で比較することです(たとえば、(4, 1) < (4, 2)これが、特定の場合に必要な順序が得られない理由です)。つまり、タプル全体ではなく、ペアタプルの最初の要素のみをソート式として使用するように指示するkey引数を関数に渡す必要があります。sorted

これにより、必要な順序が維持されることが保証されます。理由は次のとおりです。

ソートは安定していることが保証されています。つまり、複数のレコードが同じキーを持っている場合、元の順序が保持されます。

(ソース)

>>> list1 = [1, 2, 5, 4, 4, 3, 6]
>>> list2 = [3, 2, 1, 2, 1, 7, 8]
>>> 
>>> list1, list2 = (list(x) for x in zip(*sorted(zip(list1, list2), key=lambda pair: pair[0])))
>>> 
>>> print list1
[1, 2, 3, 4, 4, 5, 6]
>>> print list2
[3, 2, 7, 2, 1, 1, 8]
于 2012-12-02T10:31:11.060 に答える
0

コードでは、タプルの1番目と2番目の要素に基づいて並べ替えが実行されるため、結果の2番目のリスト要素は、最初のリストの同じ要素に対して並べ替えられた順序になります。

2番目のリストに基づくソートを回避するには、最初のリストの要素のみをタプルの比較に使用するように指定します。

>>> from operator import itemgetter
>>> list1, list2 = (list(x) for x in zip(*sorted(zip(list1, list2),key=itemgetter(0))))
>>> list1, list2
([1, 2, 3, 4, 4, 5, 6], [3, 2, 7, 2, 1, 1, 8])

itemgetter(0)最初のリストに属する各タプルから最初の要素を取得します。

于 2012-12-02T10:33:15.117 に答える