5.

Python 辞書のキー存在チェック|in・get・KeyErrorの使い方

編集
この記事の要点
  • Python の辞書(dict)で「あるキーが存在するか」を調べる最短の方法は in 演算子'key' in dTrue / False を返す。
  • 存在チェックと「値の取り出し」を同時に行いたいなら dict.get() が便利。存在しなければ既定値を返し、KeyError を出さない。
  • d.keys() を使う 'key' in d.keys() は冗長で遅いため非推奨in d だけで十分。
  • 存在しないキーを d[key] で参照すると KeyError が発生する。例外で処理するなら try / except KeyError
  • Python2 にあった has_key()Python3 で廃止。現在は使えないため in を使うこと。

 

Python の辞書(dict)であるキーが存在するかを判定する最短かつ推奨の方法は、in 演算子を使って 'キー名' in 辞書 と書くことです。結果は True(存在する)か False(存在しない)で返ります。以下では in を中心に、dict.get()try/except など各手法と使い分けを、最小サンプルコードとともに整理します。

 

in 演算子で存在チェック(推奨・最短)

もっとも簡潔で速いのが in 演算子です。キー in 辞書 と書くだけで、そのキーが辞書に存在すれば True、なければ False を返します。辞書を直接 in の右側に置くと、自動的にキーを対象に判定されます(値ではありません)。

d = {'apple': 100, 'banana': 200}

 

if 'apple' in d:

    print('apple は存在します')   # 実行される

 

print('apple' in d)   # True

print('grape' in d)   # False

 

逆に「存在しないこと」を調べたいときは not in を使います。if not ('key' in d): と書くより読みやすく、こちらが定石です。

d = {'apple': 100, 'banana': 200}

 

if 'grape' not in d:

    print('grape は存在しません')   # 実行される

 

dict.get() でデフォルト値とともに判定

「キーが存在するか」を調べつつ、存在すればその値も取り出したい場面では dict.get() が便利です。get(キー, 既定値) は、キーがあればその値を、なければ第2引数の既定値(省略時は None)を返します。d[key] と違い、存在しないキーでも KeyError を出さずに安全に扱えます。

d = {'apple': 100, 'banana': 200}

 

print(d.get('apple'))         # 100

print(d.get('grape'))         # None(KeyError にならない)

print(d.get('grape', 0))     # 0(既定値を指定)

 

# 存在チェックと値取得をまとめて

value = d.get('banana')

if value is not None:

    print(value)   # 200

 

ただし、値そのものが None になり得る辞書では、get() の戻り値が None でも「キーが無い」とは断定できません。その場合は純粋な存在判定に in を使い分けてください。

 

keys() を使う書き方と、非推奨の理由

'キー' in d.keys() と書いても結果は正しく得られますが、これは非推奨です。d.keys() はキー一覧のビューを返す呼び出しが余分に挟まるだけで、辞書そのものに in を適用する 'キー' in d と結果は同じだからです。in d はハッシュによる高速な検索(平均 O(1))で判定するため、可読性でも速度でも in d が勝ります。

d = {'apple': 100, 'banana': 200}

 

# 非推奨(冗長)

print('apple' in d.keys())   # True

 

# 推奨(シンプル&高速)

print('apple' in d)         # True

 

なお、の中に目的のものがあるかを調べたいときは in d.values() を使います。in d(= in d.keys())はあくまでキーの判定であることに注意してください。

 

try / except KeyError で例外として扱う

「キーがあるのが普通で、無いのは例外的」というケースでは、try / except KeyErrord[key] を直接参照する書き方もあります。存在しないキーを参照すると KeyError が送出されるので、それを捕捉します。

d = {'apple': 100, 'banana': 200}

 

try:

    value = d['grape']

    print(value)

except KeyError:

    print('grape は存在しません')   # 実行される

 

分岐の前にまず判定したいだけなら inget() のほうが簡潔です。例外処理は「例外的な不在」を扱う場面に向いています。

 

存在しないキーを参照すると KeyError

そもそも、なぜ存在チェックが必要になるのか。それは、辞書に無いキーを d[key] という角括弧(ブラケット)で参照すると KeyError が発生してプログラムが止まるからです。

d = {'apple': 100}

 

print(d['grape'])

# Traceback (most recent call last):

#   ...

# KeyError: 'grape'

 

これを避けるために、事前に in で確認するか、get() で安全に取り出すか、try/except で捕捉するか、のいずれかを選びます。

 

各手法の比較表

用途に応じて最適な手法は変わります。迷ったら in 演算子を基本にし、値も同時に欲しいなら get() を選ぶのが目安です。

手法 書き方 可読性 速度 向いている用途
in 演算子(推奨) 'key' in d 高い 速い 存在の有無だけを判定したい
dict.get() d.get('key', 既定値) 高い 速い 存在チェック+値の取得を同時に
keys() を使う 'key' in d.keys() やや低い やや遅い 非推奨(in d で代替可)
try / except try: d['key'] 普通 不在が多いと遅い 不在が例外的なケース

 

よくある質問

Q. キーが「存在しないこと」をチェックするには?

A. not in を使います。if 'key' not in d: と書けば、キーが無いときだけ True になります。if not ('key' in d): と同じ意味ですが、not in のほうが簡潔で読みやすいため推奨されます。

Q. キーの存在チェックと「値の存在チェック」はどう違う?

A. 'key' in dキーが存在するかの判定です。一方、辞書のの中に特定の値があるかを調べたいときは 値 in d.values() を使います。たとえば d = {'apple': 100} に対し、'apple' in dTrue ですが 100 in dFalse(キーに 100 は無い)、100 in d.values()True です。

Q. Python3 で has_key() は使える?

A. 使えません。Python2 に存在した d.has_key('key')Python3 で廃止されており、呼び出すと AttributeError になります。Python3 ではキーの存在チェックに in 演算子('key' in d)を使ってください。

 

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. 辞書の作成
  2. 値の参照
  3. 要素の追加と更新
  4. 要素の削除 (辞書 Python)
  5. キーの存在チェック
  6. dictの中身を確認する方法

最近更新/作成されたページ