I tried to search the keys in a dictionary, but I forgot to add the keys()
function. I still got the expected answer.
Why is the result the same for these t
To understand why key in dct
returns the same result as key in dct.keys()
one needs to look in the past. Historically in Python 2, one would test the existence of a key in dictionary dct
with dct.has_key(key). This was changed for Python 2.2, when the preferred way became key in dct
, which basically did the same thing:
In a minor related change, the
in
operator now works on dictionaries, sokey in dict
is now equivalent todict.has_key(key)
The behaviour of in
is implemented internally in terms of the __contains__
dunder method. Its behaviour is documented in the Python language reference - 3 Data Model:
object.__contains__(self, item)
Called to implement membership test operators. Should return true if item is in
self
, false otherwise. For mapping objects, this should consider the keys of the mapping rather than the values or the key-item pairs. For objects that don’t define__contains__()
, the membership test first tries iteration via__iter__()
, then the old sequence iteration protocol via__getitem__()
, see this section in the language reference.
(emphasis mine; dictionaries in Python are mapping objects)
In Python 3, the has_key
method was removed altogether and now there the correct way to test for the existence of a key is solely key in dict
, as documented.
In contrast with the 2 above, key in dct.keys()
has never been the correct way of testing whether a key exists in a dictionary.
The result of both your examples is indeed the same, however key in dct.keys()
is slightly slower on Python 3 and is abysmally slow on Python 2.
key in dct
returns true, if the key
is found as a key in the dct
in almost constant time operation - it does not matter whether there are two or a million keys - its time complexity is constant on average case (O(1))
dct.keys()
in Python 2 creates a list
of all keys; and in Python 3 a view of keys; both of these objects understand the key in x
. With Python 2 it works like for any iterable; the values are iterated over and True
is returned as soon as one value is equal to the given value (here key
).
In practice, in Python 2 you'd find key in dct.keys()
much slower than key in dict
(key in dct.keys()
scales linearly with the number of keys - its time complexity is O(n) - both dct.keys()
, which builds a list of all keys, and key in key_list are O(n))
In Python 3, the key in dct.keys()
won't be much slower than key in dct
as the view does not make a list of the keys, and the access still would be O(1), however in practice it would be slower by at least a constant value, and it is 7 more characters, so there is usually practically no reason to use it, even if on Python 3.