web-dev-qa-db-ja.com

Pythonで、ネストされた辞書を値でソートし、残りを別の値でソートします

この辞書形式を考えてみましょう。

{'KEY1':{'name':'google','date':20100701,'downloads':0},
 'KEY2':{'name':'chrome','date':20071010,'downloads':0},
 'KEY3':{'name':'python','date':20100710,'downloads':100}}

辞書をダウンロード順に並べ替えてから、ダウンロードのないすべてのアイテムを日付順に並べ替えてください。明らかに、辞書はソートできません。繰り返し処理できるキーのリストがソートされている必要があります。

['KEY3','KEY1','KEY2']

sortedを使用して、どちらの値でもリストを並べ替えることができますが、2番目の値で並べ替える方法も教えてください。

33
user479870

sorted()にはkey引数を使用します。これにより、並べ替えられる実際のアイテムに基づいて、並べ替えの基準となる値を返す関数を指定できます。この値がタプルの場合、タプルのソートのように、最初の値でソートされ、次に2番目の値でソートされます。

sorted(your_list, key=lambda x: (your_dict[x]['downloads'], your_dict[x]['date']))
42
Amber

key関数をsortedに渡すと、ソートする2つの項目を含むタプルが返されます。あなたの大きな辞書がdと呼ばれていると仮定します:

def keyfunc(tup):
    key, d = tup
    return d["downloads"], d["date"]

items = sorted(d.items(), key = keyfunc)

必要に応じてlambdaを使用してこれを実行できますが、これはおそらくより明確です。同等のラムダベースのコードは次のとおりです。

items = sorted(d.items(), key = lambda tup: (tup[1]["downloads"], tup[1]["date"]))

ちなみに、先ほど「ダウンロード」でソートしたいとおっしゃっていたので、上記の2つの例はダウンロード数の昇順でソートしています。ただし、コンテキストからすると、ダウンロードの降順で並べ替えることができます。その場合、次のように言います。

return -d["downloads"], d["date"]

あなたのkeyfuncに。ダウンロード数がゼロ以外の昇順で並べ替え、その後すべてのダウンロード数がゼロのレコードが必要な場合は、次のようにします。

return (-d["downloads"] or sys.maxint), d["date"]
9
Eli Courtwright

私の他の答えは間違っていました(ここでのほとんどの答えはそうです)

sorted_keys = sorted((key for key in outer_dict if outer_dict[key]['downloads']),
                     key=lambda x: (outer_dict[key]['downloads'],
                                    outer_dict[key]['downloads'])
                     reverse=True)

sorted_keys += sorted((key for key in outer_dict if not outer_dict[key]['downloads']),
                      key=lambda x: outer_dict[key]['date'])

これにより、ダウンロードされたアイテムの前に降順で並べ替えられたリストと、ダウンロードされなかった残りのアイテムが日付の後に並べ替えられたリストが作成されます。

しかし、実際には Eli Courtwrightsの回答 の最後の部分が最高です。

2
aaronasterling
a = {'KEY1':{'name':'google','date':20100701,'downloads':0},
 'KEY2':{'name':'chrome','date':20071010,'downloads':0},
 'KEY3':{'name':'python','date':20100710,'downloads':100}}


z = a.items()

z.sort(key=lambda x: (x[1]['downloads'], x[1]['date']))
0
mouad