Наиболее эффективный метод проверки наличия словарного ключа и обработки его значения, если он

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

И мы, возможно, слишком холодные, вероятно, выяснили, как это сделать. Какой из них наиболее эффективен с точки зрения скорости вычислений?

Ответ 1

Небольшой ориентир для вас (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 построения key in dict обычно быстрее, превосходит только try except случая действительного ключа, потому что он не работает, if работает.

Ответ 2

Предполагая, что вы не хотите, чтобы var1 определялся, только если установлен MyDict["key1"], очевидным решением является var1 = MyDict.get("key1", default=some_sentinel_or_default_value).

wrt/performances, это в основном зависит от того, ожидаете ли вы, что "key1" будет в вашем dict больше всего времени или нет. Если первый, блок try/except может быть быстрее, иначе он будет медленнее (try/except блоки дешевы для настройки, но дорогостоящие, когда есть реальное исключение).

Если вы действительно беспокоитесь о производительности, я предлагаю вам проверить различные варианты реальных данных с timeit модуля timeit.

Ответ 3

Этот один из ваших методов очень быстрый:

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

Предполагая определенные условия для элементов вашего словаря и хеширования, это должно быть в среднем O [1]