2009-10-04 30 views
15

複数の属性を持つPythonリストをソートする必要があります。 ALLはPython:複数の属性と混合命令による並べ替えのリスト

L.sort(key=operator.attrgetter(attribute)).... 

で簡単に属性が、問題があるためにI/Iが昇順のための混合構成を使用していることを、昇順で降順にそれを行うことができます...私がすることでビットSQLオーダー「模倣」する必要がありますあなたは "名前ASC、年DESC"のような何かをすることができます。 カスタム比較関数を実装することなく、これをPythonで簡単に行う方法はありますか?

+3

@ecatmurこの質問は他のものより古いです。複製は別の方法です。 – Jesse

答えて

26

あなたの属性が数値であれば、あなたはこれを持っています。

def mixed_order(a): 
    return (a.attribute1, -a.attribute2) 

someList.sort(key=mixed_order) 

属性に文字列やその他の複雑なオブジェクトが含まれている場合は、いくつかの選択肢があります。

.sort()の方法は安定しています。複数のパスが可能です。これはおそらく最も簡単です。それはまた非常に高速です。

def key1(a): return a.attribute1 
def key2(a): return a.attribute2 

someList.sort(key=key2, reverse=True) 
someList.sort(key=key1) 

これが唯一のソートの場合は、独自の特殊目的の比較演算子を定義できます。最小限、__eq____lt__が必要です。他の4つは、単純なロジックでこれらの2つから導き出すことができます。

+0

ありがとう! callint sort()は複数回、私にとって完璧な解決策であることが判明しました! –

+0

あなたの答えをありがとう!最初の部分についてちょっとした混乱がありました。タプルの戻り値が高いインデックス値を持つ複雑なソートを優先しますか?私の質問はもっと一般的だと思います.2つのタプルを渡したときに 'cmp'はどのようにふるまいますか?私は周りを見回し、これを見つけることができません。 –

+0

__eq__は、単純なロジックを使用して__lt__から導き出すことができます。 :) – Tony

5

あなたがすることはできませんが、比較関数を書くことは簡単です:

def my_cmp(a, b): 
    return cmp(a.foo, b.foo) or cmp(b.bar, a.bar) 
L.sort(my_cmp) 
7

カスタム関数は、コードをより読みレンダリングされます。あなたは多くのソート操作を持っていて、しかしこれらの関数を作成したくない場合は、ラムダのを使用することができます。

L.sort(lambda x, y: cmp(x.name, y.name) or -cmp(x.year, y.year)) 
関連する問題