Python 辞書にキーが存在するかどうかを確認する

辞書(「マップ」、「ハッシュ」、「連想配列」などとも呼ばれる)は、要素をキーと値のペアで保存する Python の組み込みコンテナです。

他のコンテナが数値インデックスを持つように、ここではキーをインデックスとして使用します。

キーは数値でも文字列でもかまいません。

ただし、リストのように変更可能なシーケンスやオブジェクトをキーとして使用することはできません。

今回は、Pythonで辞書にキーが存在するかどうかを調べる方法について見ていきます。

例では、この fruits_dict 辞書を使用します。

fruits_dict = dict(apple= 1, mango= 3, banana= 4)


{'apple': 1, 'banana': 4, 'mango': 3}


演算子でキーが存在するかどうかを確認します。

キーが辞書に存在するかどうかを確認する最も簡単な方法は、in 演算子を使用することです。

これは、値のメンバーシップを評価するために使用される特別な演算子です。

キーが存在する場合は True と評価され、存在しない場合は False と評価されます。

key = 'orange'


if key in fruits_dict:
    print('Key Found')
else:
    print('Key not found')


さて、この辞書には orange がないので、このような結果になります。

Key not found


これは、ほとんどの開発者が意図している、好ましいアプローチです。

内部では、 __contains__() 関数を使用して、与えられたキーが辞書に `含まれているかどうかをチェックします。

get()を使ってキーが存在するかどうかチェックする

get()関数はkeyと、そのkeyが見つからなかった場合に返すオプションの値を受け取ります。

デフォルトでは、このオプションの値はNoneです。

キーを取得してみて、返された値がNone` であれば、それは辞書に存在しないことを意味する。

key = 'orange'


if fruits_dict.get(key) == None:
    print('Key not found')
else:
    print('Key found')


この結果は

Key not found


キーが存在するかどうかをkeys()でチェックする

keys()`関数は、辞書に登録されているキーをシーケンスとして返します。

fruits_dict.keys()


このシーケンスには

dict_keys(['apple', 'mango', 'banana'])


このシーケンスを使って、キーが存在するかどうかをチェックすることができます。

これはループで行うこともできますし、in 演算子を使って行うこともできます。

key = 'orange'


if key in fruits_dict.keys():
    print('Key found')
else:
    print('Key not found')


この結果も

Key not found


has_key()を使ってキーが存在するかどうかを確認します。

手動でキーを取得して、探している値が存在するかどうかをチェックする代わりに、手軽な has_key() 関数を使用することができます。

key = 'orange'


if fruits_dict.has_key(key):
    print('Key found')
else:
    print('Key not found')


これは、キーが存在するかどうかによって True または False を返します。

このコードは次のように出力します。

Key not found


KeyError」例外の処理

存在しないキーに関する問題を回避するための興味深い方法、言い換えれば、キーが辞書に存在するかどうかをチェックする方法は、 tryexcept 節を使用して KeyError 例外を処理することです。

この例外は、プログラムが辞書にあるキーを見つけられなかったときに発生します。

これは、キー検索を扱うためのシンプルでエレガントかつ高速な方法です。

try:
    fruits_dict[key]
except KeyError as err:
    print('Key not found')


この方法は、直感的でないように聞こえるかもしれませんが、実はこれまで取り上げてきた他の方法よりもかなり高速です。

注意:例外はコードの流れを変えたり、ロジックを実装したりするために使うべきではありません。

例外が発生するのはとても速いのですが、そこから回復するのはとても遅いのです。

可能であれば、このアプローチは他のアプローチより好まれるべきではない。

どれくらいの速度で実行できるかを知るために、それらの性能を比較してみましょう。

性能比較

import timeit


code_setup = """
key = 'orange'
fruits_dict = dict(apple= 1, mango= 3, banana= 4)
"""


code_1 = """
if key in fruits_dict:
  # print('Key Found')
  pass
else:
  # print('Key not found')
  pass 
"""


code_2 = """
if fruits_dict.get(key):
  # print('Key found')
  pass
else:
  # print('Key not found')
  pass 
"""


code_3 = """
if fruits_dict.__contains__(key):
  # print('Key found')
  pass
else:
  # print('Key not found')
  pass  
"""


code_4 = """
try:
  # fruits_dict[key]
  pass
except KeyError as err:
  # print('Key not found')
  pass 
"""

code_5 = """
if key in fruits_dict.keys():
  # print('Key found')
  pass
else:
  # print('Key not found')
  pass 
"""


print('Time of code_1: ', timeit.timeit(setup = code_setup , stmt= code_1, number= 10000000))
print('Time of code_2: ', timeit.timeit(setup = code_setup , stmt= code_2, number= 10000000))
print('Time of code_3: ', timeit.timeit(setup = code_setup , stmt= code_3, number= 10000000))
print('Time of code_4: ', timeit.timeit(setup = code_setup , stmt= code_4, number= 10000000))
print('Time of code_5: ', timeit.timeit(setup = code_setup , stmt= code_5, number= 10000000))


この出力は

Time of code_1:  0.2753713619995324
Time of code_2:  0.8163219139996727
Time of code_3:  0.5563563220002834
Time of code_4:  0.1561058730003424
Time of code_5:  0.7869278369998938


最も一般的な選択肢である in 演算子の使用はかなり高速で、この問題を解決するための意図的なアプローチでもあります。

結論

この記事では、キーが辞書に存在するかどうかをチェックする複数の方法について説明しました。

そして、性能比較も行いました。

タイトルとURLをコピーしました