Check key existence in nested dictionaries

You could write a recursive function to check:

def f(d, keys):
    if not keys:
        return True
    return keys[0] in d and f(d[keys[0]], keys[1:])

If the function returns True, the keys exist:

In [10]: f(test,"abcd")
Out[10]: True

In [11]: f(test,"abce")
Out[11]: False

If you want to test multiple key combinations:

for keys in ("abce","abcr","abcd"):
    if f(test,keys):
        print(keys)
        break
abcd

To return the value it is pretty simple:

def f(d, keys):
    if len(keys) == 1:
         return d[keys[0]] if keys[0] in d else False
    return keys[0] in d and f(d[keys[0]], keys[1:])

print(f(test,"abcd"))
e

You can test again for multiple key combinations:

def test_keys(keys):
    for keys in keys:
        val = f(test,keys)
        if val:
            return val
    return False


print(test_keys(("abce","abcr","abc")))

You can also write the function iteratively:

def f(d, keys):
    obj = object
    for k in keys:
        d = d.get(k, obj)
        if d is obj:
            return False
    return d

print(f(test,"abcd"))
e

If you want to run a condition based on the return values:

def f(d, keys):
    obj = object
    for k in keys:
        d = d.get(k, obj)
        if d is obj:
            return False
    return d

from operator import mul

my_actions = {"c": mul(2, 2), "d": lambda: mul(3, 3), "e": lambda: mul(3, 3)}

for st in ("abce", "abcd", "abcf"):
    val = f(test, st)
    if val:
        print(my_actions[val]())
9

Just test the key combo in the same order you would with your if/elif's etc..


It's not exactly what you want because it doesn't check existence, but here's a one-liner similar to the dict.get method:

In [1]: test = {'a':{'b':{'c':{'d':'e'}}}}
In [2]: keys = 'abcd' # or ['a', 'b', 'c', 'd']

In [3]: reduce(lambda d, k: d.get(k) if d else None, keys, test)
Out[3]: 'e'

In [4]: keys = 'abcf'

In [5]: reduce(lambda d, k: d.get(k) if d else None, keys, test)

Unfortunately it's not very efficient because it doesn't stop as soon as one of the keys is missing.

Tags:

Python

Json