Pythonで辞書の値の最大値・最小値とそのキーを取得
Pythonで辞書(dict型オブジェクト)の値valueの最大値・最小値およびそのキーkeyを取得する方法を説明する。
例として以下の辞書を使う。
d = {'a': 100, 'b': 20, 'c': 50, 'd': 100, 'e': 80}
内容は以下の通り。
- 辞書のキー
keyの最大値・最小値を取得 - 辞書の値
valueの最大値・最小値を取得 - 辞書の値が最大・最小となるキーを取得
- 辞書の値が最大・最小となるキーと値を同時に取得
- 最大・最小となる値が複数存在する場合
辞書のキー(key)の最大値・最小値を取得
イテラブルオブジェクトの最大の要素を返す関数max()に辞書オブジェクトを渡すと、キーkeyの最大値が返る。文字列の場合はアルファベット順の最後の値となる。
max_d = max(d)
print(max_d)
# e
これは、辞書のイテレーターは要素のキーを列挙するため。
min()でも同じ。
min_d = min(d)
print(min_d)
# a
辞書の値(value)の最大値・最小値を取得
辞書のvalues()メソッドは辞書の値valueのビューを返す。
これをmax()に渡すと、辞書の値の最大値が取得できる。
max_v = max(d.values())
print(max_v)
# 100
min()でも同じ。
min_v = min(d.values())
print(min_v)
# 20
辞書の値が最大・最小となるキーを取得
辞書の値が最大・最小となるキーは以下のように取得できる。
max_k = max(d, key=d.get)
print(max_k)
# a
min_k = min(d, key=d.get)
print(min_k)
# b
max(), min()の引数keyには、各要素が比較される前にリストの各要素に適用される関数(呼び出し可能オブジェクト)を指定する。これにより、各要素そのものではなく引数keyに指定した関数の結果を比較して最大値・最小値が算出される。
ここでは引数keyに辞書のget()メソッドを指定している。get()は辞書のキーを渡してその値を返すメソッド。
上述のように辞書のイテレーターは要素のキーkeyを列挙する。そのキーを引数としてget()メソッドを適用することで値valueが返され、それに従って最大値・最小値が算出される。
辞書の値が最大・最小となるキーと値を同時に取得
辞書の値が最大・最小となるキーと値を同時に取得したい場合は、辞書のitems()メソッドを使う。items()メソッドは辞書のキーと値のタプル(key, value)のビューを返す。
max(), min()の引数keyにタプルの2要素目(= 値value)を取得する無名関数を指定すると、値valueに従って最大値・最小値が求められる。
無名関数(ラムダ式)については以下の記事を参照。
max_kv = max(d.items(), key=lambda x: x[1])
print(max_kv)
# ('a', 100)
print(type(max_kv))
# <class 'tuple'>
タプルのアンパックを利用して、それぞれ別々の変数に代入することもできる。
max_k, max_v = max(d.items(), key=lambda x: x[1])
print(max_k)
# a
print(max_v)
# 100
最小値min()でも同様。
min_kv = min(d.items(), key=lambda x: x[1])
print(min_kv)
# ('b', 20)
最大・最小となる値が複数存在する場合
これまでの例では、最大・最小となる値valueが複数存在する場合、その中のどれか一つのキーkeyまたはキーと値のタプルが返されていた。
リスト内包表記を使うことで、最大・最小となる値valueが複数存在する場合、そのキーまたはキーと値のタプルをリストとして取得できる。
- 関連記事: Pythonリスト内包表記の使い方
キーと値のタプルを取得する例。
max_kv_list = [kv for kv in d.items() if kv[1] == max(d.values())]
print(max_kv_list)
# [('a', 100), ('d', 100)]
キーのみのリストを取得する例。
max_k_list = [kv[0] for kv in d.items() if kv[1] == max(d.values())]
print(max_k_list)
# ['a', 'd']
この方法だと、最大・最小となる値valueが一つだけの場合も要素数が1のリストが取得できる。
min_kv_list = [kv for kv in d.items() if kv[1] == min(d.values())]
print(min_kv_list)
# [('b', 20)]