2016-02-28 16 views
5

内の辞書のリストのリストを並べ替え:私は辞書のリストのリストであるオブジェクト持っているのpython

myObject =[[{ "play": 5.00, "id": 1, "uid": "abc" }, \ 
      { "play": 1.00, "id": 2, "uid": "def" }], \ 
      [{ "play": 6.00, "id": 3, "uid": "ghi" }, \ 
      { "play": 7.00, "id": 4, "uid": "jkl" }], \ 
      [{ "play": 3.00, "id": 5, "uid": "mno" }, \ 
      { "play": 1.00, "id": 6, "uid": "pqr" }]] 

を、私は、各ネストされたの辞書でplay値の合計でリストをソートしたいですリスト。

sorted(myObject, key=sum(map(itemgetter(play))), reverse=True)

が働くだろう:それは、その後dictsのリストだけだったら

myObject =[[{ "play": 6.00, "id": 3, "uid": "ghi" }, \ 
      { "play": 7.00, "id": 4, "uid": "jkl" }], \ 
      [{ "play": 5.00, "id": 1, "uid": "abc" }, \ 
      { "play": 1.00, "id": 2, "uid": "def" }], \ 
      [{ "play": 3.00, "id": 5, "uid": "mno" }, \ 
      { "play": 1.00, "id": 6, "uid": "pqr" }]] 

:オブジェクトは次のようにソートされます。私はリストをループせずに和を計算し、ソートすることなくこれを行う方法を理解できません。これは私が今やっていることですが、私のリストには数百万ものリストが含まれているので、ループを削除してこのコードの効率を上げようとしています。あなたはそこにかかわらず、問題を持っています

key=sum(map(itemgetter(play))) 

:ソートとsummapplayキーにitemgetterを使用した場合

+2

メモ:この場合、末尾の '' \ ''行継続は必要ありません。行はカンマで終わり、リストリテラルはまだ "開いています"ので、Pythonは自動的に次の行がそこに続くことを期待します。 – poke

答えて

4

あなたのアイデアは、カスタムキー機能を使用するには、すでに非常に良いですkey引数ソートしているリストの項目を取る関数が必要です。しかし、sumでもmapも関数を返さないので、それをキー関数として使用することはできません。代わりに、各項目に対してこの組み合わせを実行するラムダ関数を作成することができます。

playは文字列'play'でなければならず、mapはサブリストを引数として取ります。したがって、あなたの主要な機能は次のようになります:

key=lambda x: sum(map(itemgetter('play'), x)) 

これはbtwです。より読みやすいかもしれません、次のジェネレータの理解と機能的に同等:

key=lambda x: sum(y['play'] for y in x) 

sortedでこれを使用するには、動作するはずですが、あなたは直接あなたのリストをソートする代わりにlist.sortを使用して検討する必要があります。ところで

>>> myObject = [[{ "play": 5.00, "id": 1, "uid": "abc" }, 
       { "play": 1.00, "id": 2, "uid": "def" }], 
       [{ "play": 6.00, "id": 3, "uid": "ghi" }, 
       { "play": 7.00, "id": 4, "uid": "jkl" }], 
       [{ "play": 3.00, "id": 5, "uid": "mno" }, 
       { "play": 1.00, "id": 6, "uid": "pqr" }]] 

>>> myObject.sort(key=lambda x: sum(y['play'] for y in x), reverse=True) 

>>> for x in myObject: 
     print(x) 

[{'play': 6.0, 'uid': 'ghi', 'id': 3}, {'play': 7.0, 'uid': 'jkl', 'id': 4}] 
[{'play': 5.0, 'uid': 'abc', 'id': 1}, {'play': 1.0, 'uid': 'def', 'id': 2}] 
[{'play': 3.0, 'uid': 'mno', 'id': 5}, {'play': 1.0, 'uid': 'pqr', 'id': 6}] 

を(myObjectがあります種類の悪い名前の種類のリスト)。


限り、効率問題が複雑になっても、最終的にすべてのサブリストをループする必要はありません。値を見ずにこれらの値の合計を決めることは不可能なので、明らかにこれを避けることはできません。

ただし、サブリスト内の項目を複数回確認する必要がないように、すべての合計が一度だけ計算されるようにする必要があります。幸いにも、list.sortを使用してデフォルトのソートは、まさにそれを保証ん:

リストの各項目に対応するキーを1回計算して、全体のソート処理のために使用されています。

この並べ替えの問題については、非常に効率的な解決策があります。

+0

最初に最高になるには 'reverse = True'にしてはいけません。 –

+0

@PaulRooneyああ、私はその問題の詳細を見落としていました(ソーティングの問題にはあまり関係ありません)。ありがとうございました! – poke

関連する問題