views:

31

answers:

1

I have a very large defaultdict(dict) that looks something like this:

 data['w']['x']['y']['z']={'a':5,'b':10}

I'm trying to do produce a report that lists the hierarchy of all keys navigated for a particular final dictionary. In other words, I am looking for its "full pathname" as if the last dictionary were the file and the parent pathname were the keys used to find that particular dictionary. In this case, the report would have the following line:

 w:x:y:z:a=5:b=10

I like using defaultdict, but one of the problems is pulling material out of a deeply nested defaultdict(dict).

Any help appreciated.

+1  A: 

If possible, just flatten the path:

data['w:x:y:z'] = {'a':5, 'b':10}

for path, d in data.items():
    print '%s:%s' % (path, ':'.join("%s=%r" % pair for pair in d.items()))

If the depth of the dict is exactly 4 in all cases, you can write this:

for w, wvals in data.items():
    for x, xvals in wvals.items():
        for y, yvals in xvals.items():
            for z, zvals in yvals.items():
                print '%s:%s:%s:%s:%s' % (
                    w, x, y, z,
                    ':'.join("%s=%r" % pair for pair in d.items()))

Otherwise you must resort to recursion.

def dump(data, path=''):
    if isinstance(data, defaultdict):
        for k, v in data.items():
            dump(v, path + k + ":")
    else:
        print "%s%s" % (path, ':'.join("%s=%r" % pair for pair in d.items()))

dump(data)
Jason Orendorff
Thanks. There are a couple of typos, but this gets me started. In particular, this works great when the ultimate leaf (or, file, in my analogy) is a dict() and everything above it is a defaultdict(), but not so well when there may be intervening dict's in the parent tree. Note that this is not fixable by checking for dict instances in the above conditional. I'm still working on that part.
reckoner