'key' in dict vs. dict.get ('key')

3

What is the main difference between:

>>> dic = {}
>>> existe = dic['key'] if 'key' in dic else None
>>> existe
None

Y:

>>> dic = {}
>>> existe = dic.get('key', None)
>>> existe
None

Which is the most recommended for checking keys in a dictionary?

Or is it just a matter of preferences?

    
asked by Máxima Alekz 05.04.2018 в 18:05
source

2 answers

4

For the result with both methods you get the same, in this case return the value of a key if it exists in the dictionary or None if it does not exist .

We must bear in mind that if we only want to check whether the dictionary contains a certain key (and we do not need to obtain the value associated with it), the simplest and most efficient way is to use the membership operator directly:

existe = key in dic

Where existe will be a boolean ( True / False ). In this case, it is checked if the key exists in the hash table ( __contains__ ), but its value is not obtained ( __getitem__ ).

Returning to get vs conditional, as to which is preferable, although it may be somewhat relative, the "pythonic" is to use dict.get , is readable, very compact and with the implementation in C of the overload method is sparse . There are cases in which dict.get is of great help, for example when looking for values in nested dictionaries, very typical when working with JSON:

>>> dic = {"obj1": {"foo": 4},"obj2": {"foo": 1, "bar": 3}}
>>> print(dic.get("obj2", {}).get("foo"))
1
>>> print(dic.get("obj3", {}).get("foo"))
None

There is a case in which we could consider using the construction if-else (or ternary operator as in this case) for efficiency, this is when we know in advance that the great majority of the checks go to lead to the return of the default value. In this specific case, in which the key does not exist, the overload caused by get due to the call to function makes it lose to the conditional, since in this case everything is reduced to a membership check using the operator in , a small example to measure the execution time of both methods (Python 3.6):

import timeit

def test1():
    dic[key] if key in dic else None

def test2():
    dic.get(key, None)

if __name__ =="__main__":
    dic = {k: 0 for k in range(10)}

    key = 5
    t_if =  timeit.timeit("test1()", number=10000000, setup="from __main__ import test1")
    t_get = timeit.timeit("test2()", number=10000000, setup="from __main__ import test2")   
    print("Clave EXISTE en el diccionario:",
          f"  Condicional: {t_if} segundos (10000000 loops).",
          f"     dict.get: {t_get} segundos (10000000 loops).",
          sep="\n",  end="\n\n"
         )


    key = 20
    t_if =  timeit.timeit("test1()", number=10000000, setup="from __main__ import test1")
    t_get = timeit.timeit("test2()", number=10000000, setup="from __main__ import test2")   
    print("Clave NO EXISTE en el diccionario:",
          f"  Condicional: {t_if} segundos (10000000 loops).",
          f"     dict.get: {t_get} segundos (10000000 loops).",
          sep="\n", end="\n\n"
         )
Clave EXISTE en el diccionario:
  Condicional: 2.186440394487514 segundos (10000000 loops).
     dict.get: 2.118209791485714 segundos (10000000 loops).

Clave NO EXISTE en el diccionario:
  Condicional: 1.488829632557954 segundos (10000000 loops).
     dict.get: 2.120064012042172 segundos (10000000 loops).

You can see how dict.get is practically insensitive to the existence or not of the key in the dictionary.

  

Conclusion: As a general rule, use dict.get

    
answered by 05.04.2018 / 20:52
source
1
COMPLEJIDAD:

You must bear in mind that a dictionary is a very fast and simple way of collecting data, so in a dictionary to know the keys or keys , the len or any other function will be for a time O (1) ie constant temporality, so this is much faster than a list whose complexity is O (n) , in this case we have:

  

i in dic, dic.get ()

First, as mentioned above, all the functions of a dictionary are complex O (1) but this only occurs in the get function em> but not in if you put in , why ?, simply because this is not a function of the dictionaries , get and other functions have a peculiar way of working internally with a list (a bit complex but fast), so what happens with a in dic ? , we can associate this as a for i in dic but this is not a function of python dictionaries and since it is a cycle then it simply runs through the entire dictionary so that this is of complexity O (n) (linear) which means that it goes through all elements (like the lists) until it finds the searched object.

  

In summary: the dictionaries are very good in terms of memory consumption if you manage their functions correctly, otherwise they will be of greater complexity and worse, then in conclusion the function get is the winner.

    
answered by 07.04.2018 в 03:18