Pythonの辞書は、データをキーと値のペアで格納するアイテムのコレクションです。
Python 3.7 以降のバージョンでは、辞書はアイテムの挿入順でソートされます。
それ以前のバージョンでは、順不同でした。
ここでは、辞書に含まれる値に基づいて辞書をソートする方法を見てみましょう。
forループを使った辞書の並べ替え
辞書をソートするには、for
ループを使用します。
まず、sorted()
関数を使って、辞書の値を並べ替えます。
そして、ソートされた値をループして、各値のキーを見つけます。
そして、これらのキーと値のペアを、ソートされた順番に新しい辞書に追加していきます。
注:ソートでは、辞書をインプレースで並べ替えることはできません。
並べ替えられたペアを、全く新しい空の辞書に書き込んでいるのです。
dict1 = {1: 1, 2: 9, 3: 4}
sorted_values = sorted(dict1.values()) # Sort the values
sorted_dict = {}
for i in sorted_values:
for k in dict1.keys():
if dict1[k] == i:
sorted_dict[k] = dict1[k]
break
print(sorted_dict)
これをPythonインタープリターで実行すると、次のようになります。
{1: 1, 3: 4, 2: 9}
ループを使ったソートの方法を見てきましたが、よりポピュラーな代替方法として sorted()
関数を使った方法を見てみましょう。
sorted()関数を使った辞書の並べ替え
前回は、配列の値をソートするために sorted()
関数を使いました。
辞書をソートする場合、sorted()
関数にもう一つ引数を渡すと、以下のようになります。
ここで、key
はソートのために値を比較する前に各要素に対して呼び出される関数です。
辞書オブジェクトの get()
メソッドは、辞書のキーに対応する値を返します。
sorted(dict1, key=dict1.get)` 式は、値が順番にソートされたキーのリストを返します。
ここから、ソートされた新しい辞書を作成することができます。
dict1 = {1: 1, 2: 9, 3: 4}
sorted_dict = {}
sorted_keys = sorted(dict1, key=dict1.get) # [1, 3, 2]
for w in sorted_keys:
sorted_dict[w] = dict1[w]
print(sorted_dict) # {1: 1, 3: 4, 2: 9}
sorted()関数を使うことで、
forループを使うときに書かなければならなかったコードの量を減らすことができました。
しかし、さらにsorted()関数と
itemgetter()` 関数を組み合わせることで、辞書を値でソートするためのより簡潔な解決策を得ることができます。
演算子モジュールと itemgetter() を使った辞書の並べ替え
operatorモジュールは、
itemgetter()` 関数を含んでいます。
この関数は、あるオブジェクトから項目を返す呼び出し可能なオブジェクトを返します。
例えば、itemgetter()
を使って、2
をキーとする辞書の値を返す callable オブジェクトを作成してみましょう。
import operator
dict1 = {1: 1, 2: 9}
get_item_with_key_2 = operator.itemgetter(2)
print(get_item_with_key_2(dict1)) # 9
すべての辞書は items()
メソッドにアクセスすることができます。
この関数は、辞書のキーと値のペアをタプルのリストとして返します。
このタプルのリストをソートするには、 itemgetter()
関数を使用して、タプルの2番目の値、つまり、辞書のキーの値を取得します。
ソートされたら、それらの値に基づいて辞書を作成することができます。
import operator
dict1 = {1: 1, 2: 9, 3: 4}
sorted_tuples = sorted(dict1.items(), key=operator.itemgetter(1))
print(sorted_tuples) # [(1, 1), (3, 4), (2, 9)]
sorted_dict = {k: v for k, v in sorted_tuples}
print(sorted_dict) # {1: 1, 3: 4, 2: 9}
より少ない労力で、値でソートされた辞書を手に入れることができます!
引数 key
には任意の関数を指定できるので、ラムダ関数を使って辞書の値を返せば、ソートすることができます。
では、その方法を見てみましょう。
Lambda関数による辞書の並べ替え
ラムダ関数とは、Pythonにおける無名関数、つまり名前のない関数のことです。
ラムダ関数を使えば、 itemgetter()
のために operator
モジュールをインポートしなくても、辞書の項目の値を取得することができます。
ラムバについてもっと詳しく知りたい場合は、 Python のラムダ関数ガイド を参照してください。
それでは、 sorted()
の key
引数にラムダ関数を用いて、辞書を値でソートしてみましょう。
dict1 = {1: 1, 2: 9, 3: 4}
sorted_tuples = sorted(dict1.items(), key=lambda item: item[1])
print(sorted_tuples) # [(1, 1), (3, 4), (2, 9)]
sorted_dict = {k: v for k, v in sorted_tuples}
print(sorted_dict) # {1: 1, 3: 4, 2: 9}
これまで説明してきたメソッドは、Python 3.7以降で動作することに注意してください。
それ以前のバージョンのPythonで何ができるかを見てみましょう。
値をソートした新しい辞書を返す
値で辞書をソートした後、3.7 より前のバージョンの Python でソートされた辞書を保持するには、 OrderedDict
– collections
モジュールで利用可能 – を使用する必要があります。
これらのオブジェクトは、挿入の順番を保持する辞書です。
ここでは、 OrderedDict
を使用してソートする例を紹介します。
import operator
from collections import OrderedDict
dict1 = {1: 1, 2: 9, 3: 4}
sorted_tuples = sorted(dict1.items(), key=operator.itemgetter(1))
print(sorted_tuples) # [(1, 1), (3, 4), (2, 9)]
sorted_dict = OrderedDict()
for k, v in sorted_tuples:
sorted_dict[k] = v
print(sorted_dict) # {1: 1, 3: 4, 2: 9}
結論
このチュートリアルでは、辞書をその値に基づいてソートする方法を紹介しました。
まず、2 つの for ループを使用して辞書をソートしました。
その後、 sorted()
関数を使用してソートを改善しました。
また、 operator
モジュールの itemgetter()
関数を使用することで、より簡潔なソリューションになることも確認しました。
最後に、私たちはこの解決策を Python 3.7 よりも低いバージョンで動作するように適応させました。
辞書を値でソートするには、 sorted()
関数のバリエーションが最も一般的で信頼できます。