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

47,060

Solution 1

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).

Solution 2

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.

Solution 3

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]

Share:
47,060
Lord_JABA
Author by

Lord_JABA

Updated on January 07, 2021

Comments

  • Lord_JABA
    Lord_JABA over 3 years
    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?