web-dev-qa-db-ja.com

辞書キーが存在するかどうかを確認し、存在する場合はその値を処理する最も効率的な方法

MyDict = {'key1':'value1', 'key2':'value2'}

これにはいくつかの方法があります。

if 'key1' in MyDict:
       var1 = MyDict['key1']

または

if MyDict.has_key('key1'):
       var1 = MyDict['key1']

または

if MyDict['key1']:
    var1=MyDict['key1']

または

try: 
   var1=MyDict['key1]
except KeyError, e:
   pass

または私はこのようなことを試みましたが、Pythonではこのように機能しません

if v=MyDict.get('key1'):
       var1=v

そして、私たちはおそらくそれを行うためのもっと多くの作業方法を見つけ出します。計算速度の点で最も効率的なのはどれですか?

17
Lord_JABA

ちょっとしたベンチマーク(ipython):

In [1]: def test_1(d, k):
   ...:     if k in d:
   ...:         var1 = d[k]
   ...:         

In [2]: def test_2(d, k):
   ...:     if d.has_key(k):
   ...:         var1 = d[k]
   ...:         

In [3]: def test_3(d, k):
   ...:     try:
   ...:         var1 = d[k]
   ...:     except KeyError as e:
   ...:         pass
   ...:     

In [4]: def test_4(d, k):
   ...:     if d.get(k):
   ...:         var1 = d[k]
   ...:         

In [5]: my_dict = {'key{}'.format(i): 'value{}'.format(i) for i in range(1000)}

In [6]: key_valid = "key5"

In [7]: key_non_valid = "key"

In [8]: %timeit test_1(my_dict, key_valid)
10000000 loops, best of 3: 172 ns per loop

In [9]: %timeit test_1(my_dict, key_non_valid)
10000000 loops, best of 3: 132 ns per loop

In [10]: %timeit test_2(my_dict, key_valid)
1000000 loops, best of 3: 211 ns per loop

In [11]: %timeit test_2(my_dict, key_non_valid)
10000000 loops, best of 3: 171 ns per loop

In [12]: %timeit test_3(my_dict, key_valid)
10000000 loops, best of 3: 151 ns per loop

In [13]: %timeit test_3(my_dict, key_non_valid)
1000000 loops, best of 3: 1.07 µs per loop

In [14]: %timeit test_4(my_dict, key_valid)
1000000 loops, best of 3: 246 ns per loop

In [15]: %timeit test_4(my_dict, key_non_valid)
10000000 loops, best of 3: 189 ns per loop

結論:構築key in dictは一般的に最速で、try except有効なキーの場合、if操作を実行しないため。

32
pavel_form

dont _var1_が設定されている場合にのみ_MyDict["key1"]_を定義したい場合、明らかな解決策はvar1 = MyDict.get("key1", default=some_sentinel_or_default_value)です。

wrt /パフォーマンスは、ほとんどの場合、「key1」がディクショナリにあると予想されるかどうかに依存します。最初の場合は、try/exceptブロックの方が速くなる可能性があり、そうでない場合は遅くなります(try/exceptブロックはセットアップが安価ですが、実際の例外がある場合はコストがかかります)。

パフォーマンスについて本当に心配する場合は、timeitモジュールを使用して、さまざまなオプションをテストすることをお勧めします実際のデータ上

2

このメソッドの1つは非常に高速です。

if 'key1' in MyDict:
       var1 = MyDict['key1']

辞書の項目とハッシュに特定の条件があると仮定すると、これは 平均してO [1]になります

0
StackG