Arohi Gupta
Arohi Gupta

Reputation: 93

Nested Dictionary check key value

I have a nested dictionary as shown below: (more than 2 keys "lots of lala's")

d={'lala': {'temp1': 'c', 'comp_b': 'bc', 'temp': 'b', 'comp_a': 'ac'}, 'lala1': {'temp1': 'c1', 'comp_b': 'bc1', 'temp': 'b1', 'comp_a': ''}

For all the parent keys in "a", I need to check if keys(comp_a and comp_b) have valid values. In this case, "comp_a" of "lala1" doesn't have a value. So I need my function to only return "lala" as the output.

Parent keys to check=> a= ['lala','lala1']

Required values for keys=> compulsory= ['comp_b','comp_a']

Here's what I have so far:

def check_args(a,d):
    compulsory=['comp_b','comp_a']
    valid=[]
    for a in d:
        for elements in compulsory:
            try:
                if d.get(a,{}).get(elements) !='':
                    print "Valid"
            except:
                break
        else:
            print "Can't parse details of " + a + " as mandatory data missing "
            continue

Question: How do I return the valid parent keys i.e. "lala"? Is there a better way to do what I've done so far?

Upvotes: 2

Views: 503

Answers (2)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477180

If I understood the question correctly you want to check for the dictionary values whether these have, for all compulsory elements a value?

There most certainly is a more elegant way to do this: you can use list comprehension:

e = {}
[key for key in a if all(d.get(key,e).get(c) for c in compulsory)]

The all(d.get(key,e).get(c) for c in compulsory) is crucial here since it is a filter condition. The all(..) will thus start enumerating over the compulsory list and for each element c, it will fetch that element and see if its truthiness is True. The empty string has a truthiness of False, so that won't work. If the key is not in the dictionary, then .get(c) will return None which has a truthiness of False as well.

Upvotes: 1

mitoRibo
mitoRibo

Reputation: 4548

Here is a clean way without try except

d={'lala': {'temp1': 'c', 'comp_b': 'bc', 'temp': 'b', 'comp_a': 'ac'}, 'lala1': {'temp1': 'c1', 'comp_b': 'bc1', 'temp': 'b1', 'comp_a': ''}}

compulsory= ['comp_b','comp_a']

ok_keys = [k for k,v in d.iteritems() if all([c in v and v[c]!='' for c in compulsory])]
ok_keys #<-- prints ['lala']

The logic all takes place in the list comprehension which first loops through the keys in d, and tests that all of the compulsory keys are within d[k] and that the d[k][c] values are not empty.

Upvotes: 1

Related Questions