2012-02-03 4 views
5

を用いて混合順序で文字列の2要素タプルをソートします誰かが期待しているようなソートされた結果(上記のような)。しかし、私は必要なもの要素のタプルと逆の並べ替えの最初要素に並べ替え転送することです。言い換えれば、私は次のような結果を希望:どのように、私は(ランダムにシャッフルが)次のようなものを持っている重要なパラメータ(未CMP)Pythonで

l = [('a', 'z'), 
    ('a', 'y'), 
    ('a', 'x'), 
    ('b', 'z'), 
    ('b', 'y'), 
    ('b', 'x'), 
    ] 

はPython2.xでは、この結果を達成するためにsorted()に渡すことができcmpパラメータが存在しない、しかしのpython3はもはやこれを持っています。パラメータはkeyです。 keyパラメータのみを使用して目的のソート順を達成する方法はありますか?

私はタプルをラップするためにまったく新しいクラスを定義することができますか、またはfunctools.cmp_to_key(これもラッパークラスを作成します)のようなものを使用することができますが、そのような単純な操作はすべて重いです。他の手段はありませんか?

編集:私は、文字列がすべて1文字の文字列とその、いくつかのケースでは、タプルのリストが含まれている文字列以外のデータではないことを追加する必要があります[すなわち、 (ベースストリング、日時)]。 Pythonでソート

答えて

11

は、Python 2.2のようstableあります。

>>> l.sort(key=itemgetter(0)) 
>>> l 
[('a', 'z'), ('a', 'y'), ('a', 'x'), ('b', 'z'), ('b', 'y'), ('b', 'x')] 
2

で:次に、あなたが最初値で並べ替えることができ

>>> from operator import itemgetter 
>>> l.sort(key=itemgetter(1), reverse=True) 
>>> l 
[('a', 'z'), ('b', 'z'), ('a', 'y'), ('b', 'y'), ('a', 'x'), ('b', 'x')] 

だから、あなたが最初にフラグと値で並べ替えることができますシングルステップ:

>>> l.sort(key=lambda t: (t[0], -ord(t[1]))) 
>>> l 
[('a', 'z'), ('a', 'y'), ('a', 'x'), ('b', 'z'), ('b', 'y'), ('b', 'x')] 

複数のキーを並べ替える必要があるときは、タプルが辞書編集的に比較されるため、キーの機能をタプルにすることができます。キーの1つでソートを逆にする必要がある場合は、その要素を負にします。あなたが最初ordと整数に変換する必要がありますので、明らかにあなただけの文字列が負にすることはできません。

+3

は、ソート1バイト幅のキーです。 –

0
l = [('a', 'x'), 
('a', 'y'), 
('a', 'z'), 
('b', 'x'), 
('b', 'y'), 
('b', 'z'), 
] 

>>> sorted(l, key = lambda x: 2*abs(ord(x[0])-ord('a')) + abs(ord(x[1])-ord('z') 

ホープこれは

+0

学校でのみ1バイト幅のソートキーです。 –

+0

@JohnMachin:あなたはそれを拡張していただけますか?私は本当にあなたが何を意味するのか分かりません – inspectorG4dget

+1

それはsnarky応答(と私の部分に不完全な質問)でしたが、ord()は単一の文字でのみ動作します。私が実際に作業しているコードには、マルチ文字列と非文字列データがあります。 –

1

Python Sorting HOWTOは、あなたが2回のパスでsort stabilityを利用して並べ替えを行うことをお勧めできます:

>>> l.sort(key=lambda t: t[1], reverse=True) # SECONDARY KEY: field 1 descending 
>>> l.sort(key=lambda t: t[0])     # PRIMARY KEY: field 0 ascending 
>>> l 
[('a', 'z'), ('a', 'y'), ('a', 'x'), ('b', 'z'), ('b', 'y'), ('b', 'x')] 
1

あなたがリストに二回ソート実行することによって、これを実現することができ、まず各タプルの最初の項目と新たにソートされたリスト上の通常の並べ替えを使用して、各タプルの2番目の項目と逆の並べ替えを使用して。

l = [('a', 'y'), 
    ('a', 'x'), 
    ('b', 'y'), 
    ('b', 'x'), 
    ('b', 'z'), 
    ('a', 'z'), 
    ] 
l = sorted(l, key=lambda tup: tup[1], reverse=True) 
l = sorted(l, key=lambda tup: tup[0]) 

それとも、あなたが好む場合:学校だけで

l = sorted(sorted(l, key=lambda tup: tup[1], reverse=True), 
      key=lambda tup: tup[0]) 
関連する問題