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