Most efficient method to check if dictionary key exists and process its value if it does

Question:

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

I can do this few ways:

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

or

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

or

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


or

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

or I tried something like this but it does NOT WORK like this in python

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

And we cold probably figure out lot more working ways to do that.
Which one is most efficient in terms of computing speed?

Asked By: Lord_JABA

||

Answers:

This one of your methods is very fast:

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

Assuming certain conditions on the items in your dictionary and the hashing, this should be on average O[1]

Answered By: StackG

Assuming you dont want var1 to be defined only if MyDict["key1"] is set, the obvious solution is var1 = MyDict.get("key1", default=some_sentinel_or_default_value).

wrt/ performances, it mostly depends on whether you expect “key1” to be in your dict most of the times or not. If the first, a try/except block might be faster, else it will be slower (try/except blocks are cheap to setup but costly when there’s an actual exception).

If you really worry that much about performances, I suggest you test the various options on real-life data using the timeit module.

Answered By: bruno desthuilliers

A little benchmark for you (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

Conclusion: construction key in dict is generally fastest, outperformed only by try except in case of valid key, because it doesn’t perform if operation.

(note however try except is significantly slower for invalid keys: therefore, since the whole point is you don’t know if key is valid, then given an unknown probability of valid vs. invalid, stick with key in dict).

Answered By: pavel_form
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.