dictionary python

Check if a given key already exists in a dictionary


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"
  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?


  • 31

    Calling dict.keys() creates a list of keys, according to the documentation but I’d be surprised if this pattern wasn’t optimised for, in a serious implementation, to translate to if 'key1' in dict:.

    Aug 12, 2013 at 8:51

  • 7

    So I finally found out why many of my Python scripts were so slow 🙂 :(. That’s because I’ve been using x in dict.keys() to check for keys. And that happened because the usual way to iterate over keys in Java is for (Type k : dict.keySet()), this habit causing for k in dict.keys() to feel more natural than for k in dict (which should still be fine in terms of performance?), but then checking keys becomes if k in dict.keys() too, which is a problem…

    Aug 12, 2013 at 8:58

  • 4

    @EvgeniSergeev if k in dict_: tests for presence of k in the KEYS of dict_, so you still don’t need dict_.keys(). (This has bit me, as it reads to me like its testing for a value in dict. But it isn’t.)

    Dec 16, 2013 at 23:34

  • 1

    @ToolmakerSteve That’s right, but not only do you not need it, it’s not a good practice.

    Dec 17, 2013 at 1:51

  • 26

    Try “key in dict”

    Jun 26, 2014 at 17:18


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


  • 89

    I usually just use get if I’m going to be pulling the item out of the dictionary anyway. No sense in using in and pulling the item out of the dictionary.

    Oct 21, 2009 at 19:12

  • 95

    I fully agree. But if you only need to know if a key exists, or you need to distinguish between a case where the key is defined and a case where you are using a default, in is the best way of doing it.

    – Chris B.

    Oct 21, 2009 at 19:16

  • @enkash provided the reference for Python 3. Here is the reference for Python 2.7: dict and dict.get.

    – yaobin

    Jul 23, 2015 at 13:00

  • 53

    get is a bad test if the key is equivalent to “False”, like 0 for example. Learned this the hard way :/

    – Sebastien

    Feb 9, 2016 at 21:06

  • 5

    I can’t agree that this a complete answer as it doesn’t mention that ‘try’-‘except’ will be the fastest when number of key fails is sufficiently small. See this answer below:

    Oct 5, 2017 at 1:18


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

if 'key1' in my_dict:

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.


  • 1

    doesn’t work on nested values.

    – Mujtaba

    Jun 25 at 10:32


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