yucatio@システムエンジニア

趣味で作ったものいろいろ

Pythonで辞書が格納されたリストを複数のキーで並べ変える

辞書を格納したリストがある時、複数キーで並び変える方法を紹介します。例えば、以下のような辞書が格納された配列で、まずprice順に並び変え、priceが同じだったら、weightの順番に並び変えたい場合の方法です。

list1 = [
    {'name': 'ぶどう',   'price': 5000, 'weight': 1000},
    {'name': 'もも',     'price': 3000, 'weight': 2000},
    {'name': 'りんご',   'price': 5000, 'weight': 5000},
    {'name': 'バナナ',   'price': 1500, 'weight': 1000},
    {'name': 'メロン',   'price': 5000, 'weight': 1200},
    {'name': 'マンゴー', 'price': 10000, 'weight': 900},
    {'name': 'みかん',  'price': 1500, 'weight': 5000},
]

keyにitemgetterを使用する

辞書の値で並び替える場合、itemgetter関数が便利です。

参考: ソート HOW TO — Python 3.8.1 ドキュメント

itemgetterを使用するときは、 パラメータに辞書のキー名を並び替えの優先順位の順に書きます。

sorted(list, key=itemgetter(第1キー, 第2キー, 第3キー))

まずprice順に並び変え、priceが同じだったら、weightの順番に並び変えたい場合はsorted関数のキーにitemgetter('price', 'weight')を指定します。

コードと並べ替えの結果です。

from operator import itemgetter

# list1は上記のlist1と同様
list1 = [...]

# 並べ替え
sorted_list = sorted(list1, key=itemgetter('price', 'weight'))

# 出力
print(f"{'name':<8}{'price':>8}{'weight':>8}")
print('-' * 24)
for item1 in sorted_list:
    print(f"{item1['name']:<8}{item1['price']:>8}{item1['weight']:>8}")

# name       price  weight
# --------------------------------
# バナナ         1500    1000
# みかん         1500    5000
# もも          3000    2000
# ぶどう         5000    1000
# メロン         5000    1200
# りんご         5000    5000
# マンゴー       10000     900

priceで最初に並べ替え、priceが同じ場合はweightで並び替えられています。デフォルトなのでいずれも昇順で並び替えられています。

keyにlambda関数を使用する

より一般的に複数のキーで並び替えたいときは、keyに指定する関数の戻り値にタプルを指定します。

例えば、グラム単価(price/weight)で並び替えた後、同じグラム単価であれば、priceで並び替えるようなプログラムは以下になります。

# list1は上記のlist1と同様
list1 = [...]

# 並べ替え
sorted_list = sorted(list1, key=lambda item: (item['price'] / item['weight'], item['price']))

# 出力
print(f"{'name':<8}{'price(1g)':>10}{'price':>8}{'weight':>8}")
print('-' * 34)
for item1 in sorted_list:
    print(f"{item1['name']:<8}{item1['price'] / item1['weight']:>10.2f}{item1['price']:>8}{item1['weight']:>8}")

# name     price(1g)   price  weight
# ----------------------------------
# みかん           0.30    1500    5000
# りんご           1.00    5000    5000
# バナナ           1.50    1500    1000
# もも            1.50    3000    2000
# メロン           4.17    5000    1200
# ぶどう           5.00    5000    1000
# マンゴー         11.11   10000     900

グラム単価で並び替えた後、同じグラム単価であれば、priceで並び替えることができました。 マンゴーのグラム単価高いですね。

以上でPythonで辞書が格納されたリストを複数のキーで並べ変えることができました。

環境