# Check if a given key already exists in a dictionary

Posted on

Problem :

I wanted to test if a key exists in a dictionary before updating the value for the key.
I wrote the following code:

``````if 'key1' in dict.keys():
print "blah"
else:
print "boo"
``````

I think this is not the best way to accomplish this task. Is there a better way to test for a key in the dictionary?

Solution :

`in` tests for the existence of a key in a `dict`:

``````d = {"key1": 10, "key2": 23}

if "key1" in d:
print("this will execute")

if "nonexistent key" in d:
print("this will not")
``````

Use `dict.get()` to provide a default value when the key does not exist:

``````d = {}

for i in range(10):
d[i] = d.get(i, 0) + 1
``````

To provide a default value for every key, either use `dict.setdefault()` on each assignment:

``````d = {}

for i in range(10):
d[i] = d.setdefault(i, 0) + 1
``````

or use `defaultdict` from the `collections` module:

``````from collections import defaultdict

d = defaultdict(int)

for i in range(10):
d[i] += 1
``````

Use `key in my_dict` directly instead of `key in my_dict.keys()`:

``````if 'key1' in my_dict:
print("blah")
else:
print("boo")
``````

That will be much faster as it uses the dictionary’s O(1) hashing as opposed to doing an O(n) linear search on a list of keys.

You can test for the presence of a key in a dictionary, using the in keyword:

``````d = {'a': 1, 'b': 2}
'a' in d # <== evaluates to True
'c' in d # <== evaluates to False
``````

A common use for checking the existence of a key in a dictionary before mutating it is to default-initialize the value (e.g. if your values are lists, for example, and you want to ensure that there is an empty list to which you can append when inserting the first value for a key). In cases such as those, you may find the `collections.defaultdict()` type to be of interest.

In older code, you may also find some uses of `has_key()`, a deprecated method for checking the existence of keys in dictionaries (just use `key_name in dict_name`, instead).

You can shorten your code to this:

``````if 'key1' in my_dict:
...
``````

However, this is at best a cosmetic improvement. Why do you believe this is not the best way?

For additional information on speed execution of the accepted answer’s proposed methods (10 million loops):

• `'key' in mydict` elapsed time 1.07 seconds
• `mydict.get('key')` elapsed time 1.84 seconds
• `mydefaultdict['key']` elapsed time 1.07 seconds

Therefore using `in` or `defaultdict` are recommended against `get`.

I would recommend using the `setdefault` method instead. It sounds like it will do everything you want.

``````>>> d = {'foo':'bar'}
>>> q = d.setdefault('foo','baz') #Do not override the existing key
>>> print q #The value takes what was originally in the dictionary
bar
>>> print d
{'foo': 'bar'}
>>> r = d.setdefault('baz',18) #baz was never in the dictionary
>>> print r #Now r has the value supplied above
18
>>> print d #The dictionary's been updated
{'foo': 'bar', 'baz': 18}
``````

A dictionary in Python has a `get('key', default)` method. So you can just set a default value in case there isn’t any key.

``````values = {...}
myValue = values.get('Key', None)
``````

Using the Python ternary operator:

``````message = "blah" if 'key1' in my_dict else "booh"
print(message)
``````

Use EAFP (easier to ask forgiveness than permission):

``````try:
blah = dict["mykey"]
# key exists in dict
except KeyError:
# key doesn't exist in dict
``````

See other Stack Overflow posts:

Check if a given key already exists in a dictionary

To get the idea how to do that we first inspect what methods we can call on dictionary.

Here are the methods:

``````d={'clear':0, 'copy':1, 'fromkeys':2, 'get':3, 'items':4, 'keys':5, 'pop':6, 'popitem':7, 'setdefault':8, 'update':9, 'values':10}
``````

``````Python Dictionary clear()        Removes all Items
Python Dictionary copy()         Returns Shallow Copy of a Dictionary
Python Dictionary fromkeys()     Creates dictionary from given sequence
Python Dictionary get()          Returns Value of The Key
Python Dictionary items()        Returns view of dictionary (key, value) pair
Python Dictionary keys()         Returns View Object of All Keys
Python Dictionary pop()          Removes and returns element having given key
Python Dictionary popitem()      Returns & Removes Element From Dictionary
Python Dictionary setdefault()   Inserts Key With a Value if Key is not Present
Python Dictionary update()       Updates the Dictionary
Python Dictionary values()       Returns view of all values in dictionary
``````

The brutal method to check if the key already exists may be the `get()` method:

``````d.get("key")
``````

The other two interesting methods `items()` and `keys()` sounds like too much of work. So let’s examine if `get()` is the right method for us. We have our dict `d`:

``````d= {'clear':0, 'copy':1, 'fromkeys':2, 'get':3, 'items':4, 'keys':5, 'pop':6, 'popitem':7, 'setdefault':8, 'update':9, 'values':10}
``````

Printing shows the key we don’t have will return `None`:

``````print(d.get('key')) #None
print(d.get('clear')) #0
print(d.get('copy')) #1
``````

We use that to get the information if the key is present or no.
But consider this if we create a dict with a single `key:None`:

``````d= {'key':None}
print(d.get('key')) #None
print(d.get('key2')) #None
``````

Leading that `get()` method is not reliable in case some values may be `None`.

This story should have a happier ending. If we use the `in` comparator:

``````print('key' in d) #True
print('key2' in d) #False
``````

We get the correct results.

We may examine the Python byte code:

``````import dis
dis.dis("'key' in d")
#   1           0 LOAD_CONST               0 ('key')
#               4 COMPARE_OP               6 (in)
#               6 RETURN_VALUE

dis.dis("d.get('key2')")
#   1           0 LOAD_NAME                0 (d)
#               6 CALL_METHOD              1
#               8 RETURN_VALUE
``````

This shows that `in` compare operator is not just more reliable, but even faster than `get()`.

``````try:
my_dict_of_items[key_i_want_to_check]
except KeyError:
# Do the operation you wanted to do for "key not present in dict".
else:
# Do the operation you wanted to do with "key present in dict."
``````

## Python 2 only: (and Python 2.7 supports `in` already)

You can use the `has_key()` method:

``````if dict.has_key('xyz')==1:
# Update the value for the key
else:
pass
``````

``````d = defaultdict(int)
``````

Works as well; the reason is that calling `int()` returns `0` which is what `defaultdict` does behind the scenes (when constructing a dictionary), hence the name “Factory Function” in the documentation.

A Python dictionary has the method called `__contains__`. This method will return True if the dictionary has the key, else it returns False.

``````>>> temp = {}

>>> help(temp.__contains__)

Help on built-in function __contains__:

__contains__(key, /) method of builtins.dict instance
True if D has a key k, else False.
``````

Another way of checking if a key exists using Boolean operators:

``````d = {'a': 1, 'b':2}
keys = 'abcd'

for k in keys:
x = (k in d and 'blah') or 'boo'
print(x)
``````

This returns

``````>>> blah
>>> blah
>>> boo
>>> boo
``````

Explanation

First, you should know that in Python, `0`, `None`, or objects with zero length evaluate to `False`. Everything else evaluates to `True`. Boolean operations are evaluated left to right and return the operand not True or False.

Let’s see an example:

``````>>> 'Some string' or 1/0
'Some string'
>>>
``````

Since `'Some string'` evaluates to `True`, the rest of the `or` is not evaluated and there is no division by zero error raised.

But if we switch the order `1/0` is evaluated first and raises an exception:

``````>>> 1/0 or 'Some string'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero
>>>
``````

We can use this for pattern for checking if a key exists.

``````(k in d and 'blah')
``````

does the same as

``````if k in d:
'blah'
else:
False
``````

This already returns the correct result if the key exists, but we want it to print ‘boo’ when it doesn’t. So, we take the result and `or` it with `'boo'`

``````>>> False or 'boo'
'boo'
>>> 'blah' or 'boo'
'blah'
>>>
``````

You can use a `for` loop to iterate over the dictionary and get the name of key you want to find in the dictionary. After that, check if it exist or not using `if` condition:

``````dic = {'first' : 12, 'second' : 123}
for each in dic:
if each == 'second':
print('the key exists and the corresponding value can be updated in the dictionary')
``````