By Mohan Gulati


2009-10-21 19:05:09 8 Comments

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?

21 comments

@Abdulkalek 2019-02-12 23:31:31

You can using for loop to go in each element into dictionary and get the name what you want to find in the dictionary , after that check if it exist or not like that:

dic={‘first’ : 12, ‘second’ : 123}
For each in dic :
If each == ‘second’: 
    Print (‘it is exist’)
else :
     print (‘not exist’)

@ARGeo 2019-01-12 15:03:15

To check whether a given key exists in a dictionary you should use any of the following approaches:

Approach One (working in Python 3):

def checkKey(dict, key):    
    if key in dict.keys(): 
        print("Key is here, ", end =" ") 
        print("value =", dict[key]) 
    else: 
        print("Key isn't present.") 

Let's check it:

dict = {'r': 30, 'g':59, 'b':11} 

key = 'b'
checkKey(dict, key) 

key = 'a'
checkKey(dict, key) 

Result of Approach One:

# Key is here, value = 11
# Key isn't present.

Approach Two (working in Python 3):

def checkKey(dict, key):   
    if key in dict: 
        print("Key is here, ", end =" ") 
        print("value =", dict[key]) 
    else: 
        print("Key isn't present.") 

Let's check it too:

dict = {'x': 10, 'y':20, 'z':30} 

key = 'y'
checkKey(dict, key) 

key = 'u'
checkKey(dict, key) 

Result of Approach Two:

# Key is here, value = 20
# Key isn't present.

Approach Three (working in Python 3):

def checkKey(dict, key):      
    if dict.has_key(key): 
        print "Key is here, value =", dict[key] 
    else: 
        print "Key isn't present."

Let's check it as well:

dict = {'u': 0, 'v':1, 'w':2} 

key = 'u'
checkKey(dict, key) 

key = 'm'
checkKey(dict, key)

Result of Approach Three:

# Key is here, value = 0
# Key isn't present.

Hope this helps.

@wmorris 2018-07-09 18:36:06

Why not just use the has_key() method.

a = {}
a.has_key('b') => #False

a['b'] = 8
a.has_key('b') => #True

@nijm 2018-07-09 18:55:38

This is a duplicate of other answers here. Please read the entire topic first before posting an answer. Also as mentioned in other answers: dict.has_key(key) has been deprecated in favor of key in dict.

@HungryArthur 2014-02-06 16:08:34

What about using 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 SO posts:

Using try vs if in python or

Checking for member existence in Python

@billrichards 2014-08-19 20:07:17

Try/except may be more expensive if it's likely that the key often doesn't exist. From the post you referenced: "[I]f you expect that 99 % of the time result will actually contain something iterable, I'd use the try/except approach. It will be faster if exceptions really are exceptional. If result is None more than 50 % of the time, then using if is probably better.[...][A]n if statement always costs you, it's nearly free to set up a try/except block. But when an Exception actually occurs, the cost is much higher." stackoverflow.com/a/1835844/1094092

@shuttle87 2015-07-31 14:40:35

Instead of a bare catch I'd specify except KeyError here.

@mafonya 2017-03-01 09:03:28

Dictionary in python has a get('key', default) method. So you can just set a default value in case there is no key.

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

@Leonardo Maffei 2018-02-07 22:02:16

I use the try/except; if an exception is throwed, than the key aren't present at the dictionary. example:

st = 'sdhfjaks'
d = {}
try:
    print d['st']
except Exception, e:
    print 'Key not in the dictionary'

@AFP_555 2018-10-17 23:37:36

Exceptions should not be used for regular program execution flow. So this should only be done in case the program has to be stopped if the key doesn't exist.

@Seenivasan 2017-12-09 11:55:00

Well.. You will be familiar that searching a element's existence in a list or data means going through everything (at least for unordered list e.g dict.keys ).So Instead using Exception and Errors that arise normally we can avoid that complexity...

d={1:'a',2:'b'}
try:
    needed=d[3]
    print(needed)
except:
    print("Key doesnt exist")

@Charitoo 2017-08-18 22:58:00

Using ternary operator:

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

@Siva Gnanam 2017-04-26 11:02:49

Python dictionary has the method called __contains__. This method will return True if the dictionary has the key else 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.

@user1767754 2017-11-14 18:21:17

It is very bad practice to call __contains__ directly. The correct way of doing it, is to use in operator, which is the containment check that invokes the __contains__ function.

@ron g 2019-01-08 10:03:51

@user1767754 I'm using foo = x['foo'] if x.__contains__('foo') else 'bar'. Any ideas how would might use the in operator as part of this expression?

@Jason Baker 2009-10-21 19:06:30

You don't have to call keys:

if 'key1' in dict:
  print "blah"
else:
  print "boo"

That will be much faster as it uses the dictionary's hashing as opposed to doing a linear search, which calling keys would do.

@Mohan Gulati 2009-10-21 19:20:43

That is great. I was under the impression that it would internally still traverse the list of keys, but I see this works more like testing membership in a set.

@hughdbrown 2009-10-22 02:31:39

@Mohan Gulati: You understand that a dictionary is a hashtable of keys mapped to values, right? A hashing algorithm converts the key to an integer and the integer is used to find a location in the hash table that matches. en.wikipedia.org/wiki/Hash_table

@Charles Addis 2016-04-12 16:52:00

Still, it's good practice to call keys. The 'zen' of python basically gets at the fact that code should be explicit and self documenting. Calling keys() on a dict lets anybody reading the code know, "hey this is a dict" rather than a list or a tuple.

@ivan_bilan 2016-06-20 11:25:57

@Charles Addis, from experience working with around half a million keys you get at least 10x performance boost when writing "key in dict" instead of "key in dict.keys()". PEP and Zen also states that you should ignore them in case they are bad for your project.

@Charles Addis 2016-06-20 15:33:36

ivan_bilan -- I just ran my own benchtest on this... On half a million keys, if key in d1 took 0.17265701293945312 seconds. Calling if key in d1.keys() took 0.23871088027954102 -- this is the classic definition of a micro-optimization. Saving 0.07884883880615234 seconds is not a performance boost.

@Charles Addis 2016-06-20 15:34:28

@ivan_bilan And if 0.07884883880615234 matters so much for your project constraints, you probably should not be using python.

@Eli 2016-09-06 07:55:46

@CharlesAddis and if your project need to check existence of many keys for many times - IT SHOULD BE MATTER

@Charles Addis 2016-09-06 16:54:49

@eli I ran my test on half a million keys... and here we go, I'll run the EXACT SAME TEST ON A SET OF 50,000,000 keys... So let's see how big the difference is?!

@Charles Addis 2016-09-06 19:48:48

@Eli Just for you I've created a test you can run yourself. The results may astonish you. For dicts with ~50,000 keys, not calling keys() gives you .01 second computational benefit. For ~500,000 keys, not calling keys() gives you .1 second benefit. For ~5,000,000 keys, not calling keys() is .4 seconds faster, but for 50,000,000 keys CALLING keys() IS 3 SECONDS FASTER!

@Ukimiku 2016-10-19 20:15:19

Calling key() is 3 seconds faster? Are your 5,000,000 keys unique? Otherwise, there may be many hash values that collide, and the resolution of the collisions may take some time.

@Ukimiku 2016-10-25 20:20:13

Yes, thank you. Of course, you are right. Still, two unique keys might yield the same internal hash. So with 5,000,000 keys collisions seem more likely than with 5,000 keys. But that would depend on the implementation of the hashing, and I have not looked into the code for that.

@Surest Texas 2017-03-23 18:36:37

@Ukimiku (and others). This is a very helpful presentation from pycon 2010. As you will see, collisions happen very frequently even in small record-sets (<16 items). But python handles this automatically. Looking up an item in a dictionary is practically independent of its size: pyvideo.org/pycon-us-2010/the-mighty-dictionary-55.html

@Craig Hicks 2017-10-05 01:22:55

All this testing of 'if' and no testing of 'try','except KeyError'?

@Bishwas Mishra 2016-12-21 07:05:44

The ways in which you can get the results are:

Which is better is dependent on 3 things:

  1. Does the dictionary 'normally has the key' or 'normally does not have the key'.
  2. Do you intend to use conditions like if...else...elseif...else?
  3. How big is dictionary?

Read More: http://paltman.com/try-except-performance-in-python-a-simple-test/

Use of try/block instead of 'in' or 'if':

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

@Jean Paul 2018-11-26 12:20:50

Good but need be actualized for python 3. I converted the script of the web page with 2to3, and saw that the without try syntax is always faster than the with try syntax, even in the case where the key is in the dict.

@Michael Aaron Safyan 2009-10-21 19:16:46

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

@David Locke 2009-10-21 19:28:25

dict.has_key(key) has been deprecated in favor of key in dict

@ToolmakerSteve 2013-12-16 23:19:28

Technically, has_key is deprecated for Python 2.x+ (not merely for 3.0+). That is, new code is recommended to not use it, even when writing in Python 2.x. (Because it is a feature known to be going away in future versions, and there is a perfectly good substitute to use instead.) What happens in 3.0 is that it is removed completely.

@kqr 2014-11-06 13:02:28

@ToolmakerSteve You are of course correct and I updated the answer to reflect that. :)

@Ido_f 2015-01-26 18:15:17

Wanted to share that (using Python 2.7) the run time of something I just wrote, basing heavily on dicts, was 363.235070 using "key in dict.keys()" and drastically went down to 0.260186 solely by removing the call for "keys()"

@Charles Addis 2016-06-21 21:33:09

@Ido_f please post your benchmarks, as my benchmarks almost no difference in 3.5 and 2.7

@Charles Addis 2016-06-21 21:34:16

@Ido_f I suspect it was something else in your program that was something else, but not actually key in dict.keys(). Try removing all code except for this check and see what your result is.

@Debabrata 2015-09-10 18:37:27

For checking you can use has_key() method

if dict.has_key('key1'):
   print "it is there"

If you want a value then you can use get() method

a = dict.get('key1', expeced_type)

If you want a tuple or list or dictionary or any string as a default value as return value, then use get() method

a = dict.get('key1', {}).get('key2', [])

@Padraic Cunningham 2015-12-14 19:58:50

.get and has_key have already been suggested in answers years before yours, has_key has also been removed in python3

@Tasneem Haider 2016-06-13 05:44:35

Easiest one is if you know which key(key name) is to look for:

# suppose your dictionary is
my_dict = {'foo': 1, 'bar': 2}
# check if a key is there
if 'key' in my_dict.keys():   # it will evaluates to true if that key is present otherwise false.
    # do something

or you can also do simply as:

if 'key' in my_dict:   # it will evaluates to true if that key is present otherwise false.
    # do something

@Arun Thundyill Saseendran 2017-08-07 10:49:00

Repetition of the answer. This is not encouraged here. Please read through the already existing answers and ensure that you are not repeating the same answer.

@gounc86 2015-07-15 18:55:45

print dict.get('key1', 'blah')

Won't print boo for the values in the dict, but accomplishes the goal by printing the value of key1 to confirm it's existence instead.

@Wtower 2015-05-29 11:06:44

For additional info on speed execution of the accepted answer's proposed methods (10m loops):

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

Therefore using in or defaultdict are recommended against get.

@scape 2015-06-11 23:02:27

get is in essence the combination of bullet points 1 and 3..

@Paul Rigor 2017-06-15 16:59:33

totally agree that get's 1.84s is < 1.07*2 ;-P

@Umair 2018-12-28 12:34:06

@PaulRigor LOL, first check if exists, then get it separately

@wan kenobi 2013-05-09 10:17:15

You can use the has_key() method:

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

Or the dict.get method to set a default value if not found:

mydict = {"a": 5}

print mydict["a"]            #prints 5
print mydict["b"]            #Throws KeyError: 'b'

print mydict.get("a", 0)     #prints 5
print mydict.get("b", 0)     #prints 0

@Brad Koch 2013-05-11 16:50:42

.has_key() has been deprecated; you should use in as shown in other answers.

@ToolmakerSteve 2013-12-16 23:58:09

BTW, I recommend reading ALL existing answers to an OLD question, before answering it. This answer added nothing, since the suggestion already existed in Michael's answer, from '09. (I don't mean to discourage an attempt to add something useful to a discussion. Keep trying.)

@Kuldeep Singh Dhaka 2016-08-20 19:14:02

Wan Kenobi Please put @brad-kock comment on top. Indeed the answed has its own value but is not recommendable (not available atleast on Python 3.5.2).

@Mauricio Morales 2013-05-19 18:12:35

Just an FYI adding to Chris. B (best answer):

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.

@ToolmakerSteve 2013-12-17 00:03:46

(I gave you the +1, because Chris' defaultdict(lambda: 0) seemed obscure to me. saying "this is a dictionary of int's, so they start with the default value of an int, e.g. int() e.g. 0" I like.)

@Chris B. 2014-02-03 19:35:29

If you're creating a dictionary of counts, you should be using Counter (assuming Python 2.7). And I used defaultdict(lambda: 0) instead of defaultdict(int) because I think it's clearer what's going on; the reader doesn't need to know you get 0 if you call int() without arguments. YMMV.

@Chris B. 2009-10-21 19:10:21

in is the intended way to test for the existence of a key in a dict.

d = dict()

for i in xrange(100):
    key = i % 10
    if key in d:
        d[key] += 1
    else:
        d[key] = 1

If you wanted a default, you can always use dict.get():

d = dict()

for i in xrange(100):
    key = i % 10
    d[key] = d.get(key, 0) + 1

... and if you wanted to always ensure a default value for any key you can use defaultdict from the collections module, like so:

from collections import defaultdict

d = defaultdict(lambda: 0)

for i in xrange(100):
    d[i % 10] += 1

... but in general, the in keyword is the best way to do it.

@Jason Baker 2009-10-21 19:12:49

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.

@Chris B. 2009-10-21 19:16:36

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.

@enkash 2015-01-28 05:54:11

Reference for this answer is at the python docs

@yaobin 2015-07-23 13:00:15

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

@Sebastien 2016-02-09 21:06:22

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

@Alg_D 2016-03-08 19:48:48

This is a great example and males all sense for numbers, but what if the key is a string/text and the value a list? In this case, how to perform same check and either add a new key with list (one element) or update/add new element to the list?

@Marko Mackic 2017-01-14 03:05:05

@Algina the same way :)

@Craig Hicks 2017-10-05 01:18:01

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: stackoverflow.com/a/1602945/4376643

@hajef 2019-02-26 14:51:02

Is it just me or doesn't this "answer" match the question let alone answer it? I at least are more confused now and I can't even confirm the solution actually works.

@David Berger 2009-10-21 19:07:28

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}

@hughdbrown 2009-10-21 19:11:11

What does setdefault have to do with the OP's question?

@David Berger 2009-10-21 19:14:14

@hughdbrown "I wanted to test if a key exists in a dictionary before updating the value for the key." Sometimes posts include code that generate a flurry of responses to something that's not quite the original goal. To accomplish the goal stated in the first sentence, setdefault is the most effective method, even though it's not a drop-in replacement for the sample code posted.

@Niels Bom 2012-07-24 13:07:37

This is the superior answer because it satisfies OP's goal instead of just giving the technically correct answer. See: nedbatchelder.com/blog/201207/…

@ToolmakerSteve 2013-12-16 23:42:26

+1 for an informative answer, that taught me something. However, whether it is the best solution depends on what the coder has in mind; e.g. the meaning of "before updating the value of the key". Maybe he's going to throw an exception if it is not present (== no permission to add new keys). Maybe its a dictionary of counts, and he's going to add 1 to the existing count, in which case `d[key] = d.get(key, 0) + 1' is the cleanest solution (as Chris shows, after your answer was written). (I only bother mentioning this, in case future readers come here, with different tasks in mind.)

@ToolmakerSteve 2013-12-16 23:46:11

@NielsBom ... IMHO setdefault is only the superior solution when an existing entry should not be overwritten. (An important case, but not the only reason to be testing existence of a key.)

@Niels Bom 2013-12-17 12:38:17

@ToolmakerSteve True. The problem here is that OP's question was not clear enough.

@Greg Hewgill 2009-10-21 19:06:40

You can shorten this:

if 'key1' in dict:
    ...

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

@Jason Baker 2009-10-21 19:08:19

This is much more than a cosmetic improvement. The time to find a key using this method is O(1) whereas calling keys would generate a list and be O(n).

@spectras 2015-08-22 18:08:54

The O(1) does not seem quite right. Are you sure it's not something like O(log n)?

@Leonora Tindall 2015-10-28 00:18:40

It's the complexity of a single dict lookup, which is on average O(1) and at worst O(n). .list() will always be O(n). wiki.python.org/moin/TimeComplexity

@nurettin 2018-12-09 09:19:28

this also avoids an extra allocation. (important for making tight loops a bit faster)

Related Questions

Sponsored Content

42 Answered Questions

[SOLVED] How do I sort a dictionary by value?

42 Answered Questions

[SOLVED] How do I check whether a file exists without exceptions?

43 Answered Questions

[SOLVED] How to merge two dictionaries in a single expression?

29 Answered Questions

[SOLVED] Finding the index of an item given a list containing it in Python

  • 2008-10-07 01:39:38
  • Eugene M
  • 3150767 View
  • 2595 Score
  • 29 Answer
  • Tags:   python list

13 Answered Questions

[SOLVED] Iterating over dictionaries using 'for' loops

35 Answered Questions

[SOLVED] How do I check if a list is empty?

  • 2008-09-10 06:20:11
  • Ray Vega
  • 2111183 View
  • 3152 Score
  • 35 Answer
  • Tags:   python list

14 Answered Questions

[SOLVED] Add new keys to a dictionary?

  • 2009-06-21 22:07:39
  • lfaraone
  • 2815903 View
  • 2171 Score
  • 14 Answer
  • Tags:   python dictionary

26 Answered Questions

[SOLVED] What is the best way to iterate over a dictionary?

  • 2008-09-26 18:20:06
  • Jake Stewart
  • 1312965 View
  • 2199 Score
  • 26 Answer
  • Tags:   c# dictionary loops

11 Answered Questions

[SOLVED] Use of *args and **kwargs

  • 2010-08-03 08:28:07
  • MacPython
  • 799736 View
  • 1280 Score
  • 11 Answer
  • Tags:   python args kwargs

8 Answered Questions

[SOLVED] How to remove a key from a Python dictionary?

Sponsored Content