Pythonで辞書の値の最大値・最小値とそのキーを取得
Pythonで辞書(dict
型オブジェクト)の値value
の最大値・最小値およびそのキーkey
を取得する方法を説明する。
例として以下の辞書を使う。
d = {'a': 100, 'b': 20, 'c': 50, 'd': 100, 'e': 80}
以下の内容について説明する。
- 辞書のキー
key
の最大値・最小値を取得 - 辞書の値
value
の最大値・最小値を取得 - 辞書の値が最大・最小となるキーを取得
- 辞書の値が最大・最小となるキーと値を同時に取得
- 最大・最小となる値が複数存在する場合
pandas.Series
に変換して処理
辞書のキー(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)
ラムダ式ではなく標準ライブラリoperatorのitemgetter()
を利用する方法もある。以下の記事を参照。
最大・最小となる値が複数存在する場合
これまでの例では、最大・最小となる値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)]
pandas.Seriesに変換して処理
辞書をpandas.Series
に変換してから処理することも可能。
コンストラクタpd.Series()
に辞書を指定するとキーがindex
、値がvalues
のpandas.Series
が生成される。
import pandas as pd
d = {'a': 100, 'b': 20, 'c': 50, 'd': 100, 'e': 80}
s = pd.Series(d)
print(s)
# a 100
# b 20
# c 50
# d 100
# e 80
# dtype: int64
print(s.index)
# Index(['a', 'b', 'c', 'd', 'e'], dtype='object')
print(s.values)
# [100 20 50 100 80]
辞書の値(value)の最大値・最小値を取得
pandas.Series
のメソッドmax()
, min()
で元の辞書の値value
の最大値・最小値を取得できる。組み込み関数max()
, min()
を使う。
print(s.max())
# 100
print(s.min())
# 20
辞書のキー(key)の最大値・最小値を取得
pandas.Series
のindex
の最大値・最小値が元の辞書のキーkey
の最大値・最小値となる。
print(max(s.index))
# e
print(min(s.index))
# a
辞書の値が最大・最小となるキーを取得
pandas.Series
のメソッドidxmax()
, idxmin()
で元の辞書の値が最大・最小となるキーを取得できる。最大値・最小値が複数ある場合は最初のキーのみが返される。
print(s.idxmax())
# a
print(s.idxmin())
# b
最大値・最小値が複数ある場合にすべてのキーを取得したい場合は、最大値・最小値に等しい要素をブールインデックス参照で抽出し、index
属性を取得する。
print(s[s == s.max()])
# a 100
# d 100
# dtype: int64
print(s[s == s.max()].index)
# Index(['a', 'd'], dtype='object')
リスト型にしたい場合はIndex
のtolist()
メソッドかlist()
を使う。
print(s[s == s.max()].index.tolist())
# ['a', 'd']
print(list(s[s == s.max()].index))
# ['a', 'd']
最小値の場合も同様。この方法の場合、該当するキーが一つだけの場合もIndex
やリストで返される。
print(s[s == s.min()])
# b 20
# dtype: int64
print(s[s == s.min()].index)
# Index(['b'], dtype='object')
print(s[s == s.min()].index.tolist())
# ['b']
print(list(s[s == s.min()].index))
# ['b']
その他の処理
辞書をpandas.Series
に変換すると、ソートや条件抽出などをするのも簡単で便利。
- 関連記事: pandas.DataFrame, Seriesをソートするsort_values, sort_index
- 関連記事: pandasで複数条件のAND, OR, NOTから行を抽出(選択)
print(s.sort_values())
# b 20
# c 50
# e 80
# a 100
# d 100
# dtype: int64
print(s[s > 60])
# a 100
# d 100
# e 80
# dtype: int64