6

I have some Python dictionaries like this:

A = {id: {idnumber: condition},.... 

e.g.

A = {1: {11 : 567.54}, 2: {14 : 123.13}, .....

I need to search if the dictionary has any idnumber == 11 and calculate something with the condition. But if in the entire dictionary doesn't have any idnumber == 11, I need to continue with the next dictionary.

This is my try:

for id, idnumber in A.iteritems():
    if 11 in idnumber.keys(): 
       calculate = ......
    else:
       break
dreftymac
  • 31,404
  • 26
  • 119
  • 182
Alejandro
  • 4,945
  • 6
  • 32
  • 30
  • **see also**: https://stackoverflow.com/questions/14692690/access-nested-dictionary-items-via-a-list-of-keys – dreftymac Jul 12 '18 at 20:53

2 Answers2

7

dpath to the rescue.

http://github.com/akesterson/dpath-python

dpath lets you search by globs, which will get you what you want.

$ easy_install dpath
>>> for (path, value) in dpath.util.search(MY_DICT, '*/11', yielded=True):
>>> ... # 'value' will contain your condition; now do something with it.

It will iterate out all of the conditions in the dictionary, so no special looping constructs required.

See also

dreftymac
  • 31,404
  • 26
  • 119
  • 182
  • This is a pervasive repeating question and `dpath` is hardly given enough recognition, despite it being a very straightforward solution, so linking here for better exposure. – dreftymac Oct 30 '17 at 19:53
7

You're close.

idnum = 11
# The loop and 'if' are good
# You just had the 'break' in the wrong place
for id, idnumber in A.iteritems():
    if idnum in idnumber.keys(): # you can skip '.keys()', it's the default
       calculate = some_function_of(idnumber[idnum])
       break # if we find it we're done looking - leave the loop
    # otherwise we continue to the next dictionary
else:
    # this is the for loop's 'else' clause
    # if we don't find it at all, we end up here
    # because we never broke out of the loop
    calculate = your_default_value
    # or whatever you want to do if you don't find it

If you need to know how many 11s there are as keys in the inner dicts, you can:

idnum = 11
print sum(idnum in idnumber for idnumber in A.itervalues())

This works because a key can only be in each dict once so you just have to test if the key exits. in returns True or False which are equal to 1 and 0, so the sum is the number of occurences of idnum.

agf
  • 171,228
  • 44
  • 289
  • 238
  • hi @agf thanks for your help. btw, what should I do if I want to count the number of 11 in idnumber?? THANKS!!! :) – Alejandro Oct 07 '11 at 02:07
  • I'm not sure of your question? `idnumber` is a `dict`, and `idnum` is a key in that `dict`, so there can only be one `idnum` in each `idnumber`. If you mean the total number of `idnumber` dicts that have `11`s as keys I'll add it to my answer. – agf Oct 07 '11 at 02:19
  • sorry, I didn't explain correctly. those dictionaries are in a way that id is like a counting for each idnumber, i.e. like this `{1: {15: 67.4}, 2: {13: 78.4}, 3: {11 : 723.73}, 4: {11 : 34.21}...` so I need to count how many 11 are in all idnumbers in each dict. Thanks for your time!!! :) – Alejandro Oct 07 '11 at 03:11
  • 1
    @Alejandro That's what the code I added to the bottom of my answer does. – agf Oct 07 '11 at 03:18