14

Is there a single line method to check whether a Python 2d dict has an inner key/value?

Right now i do somethng like this:

if d.has_key(k1):
    if d[k1].has_key(k2): 
        # do something

Is there a better way to do this?

Thanks

Eli Courtwright
  • 186,300
  • 67
  • 213
  • 256
frazman
  • 32,081
  • 75
  • 184
  • 269

6 Answers6

23
if k2 in d.get(k1, {}):
    # do something

The above fragment is nice if you don't care about whether k1 actually exists or not and merely want to know whether k2 exists inside of it if it does exist. As you can see from my code snippet, I prefer the in operator, but you could just as easily say

if d.get(k1, {}).has_key(k2):
    # do something

if you prefer that idiom, but the has_key method has been deprecated in Python 3.x, so you should probably avoid it.

Eli Courtwright
  • 186,300
  • 67
  • 213
  • 256
14

You can use in:

if k1 in d and k2 in d[k1]:

The has_key method is deprecated and is removed in Python 3.x.

Related:

Community
  • 1
  • 1
Mark Byers
  • 811,555
  • 193
  • 1,581
  • 1,452
6

I don't have enough reputation to comment, but please note that the top suggestion will fail if the value of key1 is None.

if k2 in d.get(k1, {}):
    # do something

fails if d = {'k1': None} so be sure of the value of your keys.

fizloki
  • 151
  • 3
  • 5
4
if d.has_key(k1) and d[k1].has_key(k2): 
bpgergo
  • 15,669
  • 5
  • 44
  • 68
2

The answer to your first question is yes. I consider Eli's answer

if k2 in d.get(k1, {}):

the best one liner as it avoids looking up k1 in d twice. The answer to your second question depends on what you want to do if either test fails and if you want to do something different in the two failure cases. If so:

try:
    d1 = d[k1]
    if k2 in d1:
        <both tests passed>
    else:
        <second test failed>
except KeyError:
    <first test failed>
Terry Jan Reedy
  • 18,414
  • 3
  • 40
  • 52
1

Don't use has_key() use get() as has_key() has been deprecated in python 3.x :

d.get(k1,None) and d[k1].get(k2,None): 
Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504