Fynn Mahoney
Fynn Mahoney

Reputation: 737

Check if items in a list exist in dictionary

My question might be a little complicated to understand but here's actually the thing. I have a nested dictionary that looks like this:

dict_a = {'one': {'bird':2, 'tree':6, 'sky':1, 'TOTAL':9},
          'two': {'apple':3, 'sky':1, 'TOTAL':4},
          'three': {'tree':6, 'TOTAL':6},
          'four': {'nada':1, 'TOTAL':1},
          'five': {'orange':2, 'bird':3, 'TOTAL':5}
          }

and a list:

list1 = ['bird','tree']
newlist = []

how can I check the items in list1 whether it is in the nested dictionary of dict_a and append it to the newlist? The output should look like this:

newlist = ['one','three','five']

since bird and tree happened to be in the nested dictionary of one, three and five.

What I can think of is:

for s,v in dict_a.items():
    for s1,v1 in v.items():
        for item in list1:
            if item == s1:
               newlist.append(s)

Upvotes: 6

Views: 6377

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1122082

Make list1 a set and use dictionary views, and a list comprehension:

set1 = set(list1)
newlist = [key for key, value in dict_a.iteritems() if value.viewkeys() & set1]

In Python 3, use value.keys() and dict_a.items instead.

This tests if there is a set intersection between the dictionary keys and the set of keys you are looking for (an efficient operation).

Demo:

>>> dict_a = {'one': {'bird':2, 'tree':6, 'sky':1, 'TOTAL':9},
...           'two': {'apple':3, 'sky':1, 'TOTAL':4},
...           'three': {'tree':6, 'TOTAL':6},
...           'four': {'nada':1, 'TOTAL':1},
...           'five': {'orange':2, 'bird':3, 'TOTAL':5}
...           }
>>> set1 = {'bird','tree'}
>>> [key for key, value in dict_a.iteritems() if value.viewkeys() & set1]
['three', 'five', 'one']

Note that dictionary ordering is arbitrary (depending on the keys used and dictionary insertion and deletion history), so the output list order may differ.

Technically speaking, you can use your list directly too (value.viewkeys() & list1 works) but making it a set states your intention more clearly.

Upvotes: 4

Related Questions