2

I have a dictionary as follows:

  D = { "America": { "Washington": { "Seattle": ('park', 'museum'), "Kent": ("market",) }, 'Colorado': { "Boulder": ("hiking",) } } }

how can I make the following results using that dictionary.

America Wahington Seattle park
America Wahington Seattle museum
America Wahington Kent market
America Colorado Boulder hiking

I tried as follows:

for x in D.iteritems(): print x

Could not figure out how to extract each elements after that. Alos wan to to how is the good way of getting the above result.

dragon
  • 23
  • 5
  • 1
    If it is always nested three levels deep as in your example, you have to use a three level nested `for` loop too. Or use recursion. – Selcuk Oct 10 '16 at 03:23
  • You can work into the direction of flattening the dictionary to solve it in a generic fashion: http://stackoverflow.com/questions/6027558/flatten-nested-python-dictionaries-compressing-keys. – alecxe Oct 10 '16 at 03:24

4 Answers4

1

This versions should be more readable for you. But they are not so universal like other versions.

for country in D:
    for state in D[country]:
        for city in D[country][state]:
            for place in D[country][state][city]:
                print(country, state, city, place)


for country, A in D.items():
    for state, B in A.items():
        for city, C in B.items():
            for place in C:
                print(country, state, city, place)
furas
  • 134,197
  • 12
  • 106
  • 148
  • +1 for lols... I don't even think to write specific solutions 9/10 times, and honestly this didn't even occur to me :p – kpie Oct 10 '16 at 03:39
0

Here is a solution almost entirely based on the "recursive"-approach answer for the "flattening the dictionary" problem:

import collections


def flatten(d, parent_key='', sep=' '):
    items = []
    for k, v in d.items():
        new_key = parent_key + sep + k if parent_key else k
        if isinstance(v, collections.MutableMapping):
            items.extend(flatten(v, new_key, sep=sep).items())
        else:
            items.append((new_key, v))
    return dict(items)

Usage:

$ ipython -i test.py
In [1]: D = {"America": {"Washington": {"Seattle": ('park', 'museum'), "Kent": ("market",)},
   ...:                  'Colorado': {"Boulder": ("hiking",)}}}

In [2]: for key, values in flatten(D, sep=" ").items():
   ...:     for value in values:
   ...:         print(key + " " + value)
   ...:         
America Washington Seattle park
America Washington Seattle museum
America Colorado Boulder hiking
America Washington Kent market

One of the biggest advantages of this approach is that it is scalable - it would work for different depths of the dictionary D.

Community
  • 1
  • 1
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
0

Recursion is your friend...

D = { "America": { "Washington": { "Seattle": ('park', 'museum'), "Kent": ("market",) }, 'Colorado': { "Boulder": ("hiking",) } } }

def printOut(d,s):
    if(type(d)==dict):
        for k in d.keys():
            printOut(d[k],s+" "+str(k)) # add the key to a string and pass the contained dictionary and the new string to the same function. (this is the recursive part...)
    else:
        try:                      # this try catch allows the method to handle iterable and non-iterable leaf nodes in your dictionary.
            for k in d:
                print s+" "+str(k)
        except TypeError:
                print s+" "+str(d)

printOut(D,"")

prints::

 America Washington Seattle park
 America Washington Seattle museum
 America Washington Kent market
 America Colorado Boulder hiking

notice that there is a leading space so this code might fail a test if it looking for a specific output, to eliminate the leading space we would simply add the line s = s[1:] if len(s)>0 else s immediately after the else.

kpie
  • 9,588
  • 5
  • 28
  • 50
0

I would suggest recursive solution to work with your different kind of data:

def printX(data, prefix=''):
    if isinstance(data, dict):
        for itemKey, itemValue in data.iteritems():
            newPrefix = '{} {}'.format(prefix, itemKey)
            printX(itemValue, newPrefix)
    elif isinstance(data, tuple):
        for itemValue in data:
            printX(itemValue, prefix)
    else:
        print('{} {}'.format(prefix, data))

Did a test as below:

D = {
    'America': { 
        'Washington': {
            'Seattle': ('park', 'museum'),
            'Kent': ('market',) 
        },
        'Colorado': {
            'Boulder': ('hiking',)
        } 
    } 
}
printX(D)

Output is as below

America Washington Seattle park
America Washington Seattle museum
America Washington Kent market
America Colorado Boulder hiking