13

私の質問は、これらの 2 つのリンク12に非常に似ています。

3 つの異なるリストがあります。List2 に基づいて List1 を並べ替えたい (昇順)。ただし、List2 には繰り返しがあります。次に、これらの繰り返しを List3 (降順) で並べ替えます。十分に混乱しますか?

私が持っているもの:

List1 = ['a', 'b', 'c', 'd', 'e']
List2 = [4, 2, 3, 2, 4]
List3 = [0.1, 0.8, 0.3, 0.6, 0.4]

私が欲しいもの:

new_List1 = ['b', 'd', 'c', 'e', 'a']

0.8 > 0.6 であるため、'b' は 'd' の前に来ます。0.4 > 0.1 であるため、'e' は 'a' の前に来ます。

4

3 に答える 3

13

次の方法でこれを行うことができるはずだと思います:

paired_sorted = sorted(zip(List2,List3,List1),key = lambda x: (x[0],-x[1]))
l2,l3,l1 = zip(*paired_sorted)

実際に:

>>> List1 = ['a', 'b', 'c', 'd', 'e']
>>> List2 = [4, 2, 3, 2, 4]
>>> List3 = [0.1, 0.8, 0.3, 0.6, 0.4]
>>> paired_sorted = sorted(zip(List2,List3,List1),key = lambda x: (x[0],-x[1]))
>>> l2,l3,l1 = zip(*paired_sorted)
>>> print l1
('b', 'd', 'c', 'e', 'a')

仕組みは次のとおりです。まず、 を使用して、リストから対応する要素を照合しますzip。次に、最初に List2 の項目、2 番目に (否定された) List3 の項目に基づいて、これらの要素を並べ替えます。次に、引数のアンパッキングを使用して List1 要素を再度取り出す必要がありzipますが、1 日の終わりにタプルの代わりにリストがあることを確認したい場合は、リスト内包表記を使用して簡単に行うことができます。

List3 の値を簡単に否定できない場合 (たとえば、文字列の場合)、これは少し難しくなります。2 つのパスで並べ替えを行う必要があります。

paired = zip(List2,List3,List1)
rev_sorted = sorted(paired,reverse=True,key=lambda x: x[1])  #"minor" sort first
paired_sorted = sorted(rev_sorted,key=lambda x:x[0])         #"major" sort last
l2,l3,l1 = zip(*paired_sorted)

(必要に応じて、上記operator.itemgetter(1)の代わりに使用できますlambda x:x[1])。これは、Python の並べ替えが「安定」しているため機能します。「等しい」要素を並べ替えることはありません。

于 2012-12-19T17:19:09.443 に答える
5

これには、装飾 - 並べ替え - 装飾解除の手順が必要です。

decorated = zip(List1, List2, List3)
decorated.sort(key=lambda v: (v[1], -v[2]))
new_list1 = [v[0] for v in decorated]

または、1 行にまとめます。

new_list1 = [v[0] for v in sorted(zip(List1, List2, List3), key=lambda v: (v[1], -v[2]))]

出力:

>>> List1 = ['a', 'b', 'c', 'd', 'e']
>>> List2 = [4, 2, 3, 2, 4]
>>> List3 = [0.1, 0.8, 0.3, 0.6, 0.4]
>>> new_list1 = [v[0] for v in sorted(zip(List1, List2, List3), key=lambda v: (v[1], -v[2]))]
>>> new_list1
['b', 'd', 'c', 'e', 'a']
于 2012-12-19T17:19:26.147 に答える
3
>>> [v for i, v in sorted(enumerate(List1), key=lambda i_v: (List2[i_v[0]], -List3[i_v[0]]))]
['b', 'd', 'c', 'e', 'a']

これは、インデックスを使用してインデックスと値のペアを並べ替え、他のリストから対応する値を取得して、による順序付けに使用されるキー関数で使用sorted()し、リスト内包表記を使用して値のみを抽出します。

これは、インデックスのみを並べ替えてから、それらのインデックスを使用して次の値から値を取得する、より短い代替手段ですList1

>>> [List1[i] for i in sorted(range(len(List1)), key=lambda i: (List2[i], -List3[i]))]
['b', 'd', 'c', 'e', 'a']
于 2012-12-19T17:20:18.847 に答える