I need to traverse a dictionary recursively and remember the previous keys.
Let me explain:
dic = {u'resources': {u'info': {u'load': (u'37', u'17')}}, u'peak': {u'load': (u'0', u'1')}}
The elements are always a value or a dictionary until it reaches a value.
I want to print the above dic
like this: (omit the xxx below, it should eventually be a diff of the two values)
resources info load 37 17 xxx
resources peak load 0 1 xxx
This is the code I have so far:
def convertToTable(var):
if isinstance(var, tuple):
if len(var) != 2:
return str(var)
v1, v2 = var
try:
v1 = float(v1)
v2 = float(v2)
except ValueError:
pass
if type(v1) != type(v2):
return '\t%s\t%s\n' % (v1, v2)
elif isinstance(v1, int) or isinstance(v1, float):
sign = '+' if v2 - v1 > 0 else ''
return '\t%s\t%s\t%s%s\n' % (v1, v2, sign, v2 - v1)
elif isinstance(v1, list):
ret = ''
for i in range(max(len(v1), len(v2))):
v1v = v1[i] if i < len(v1) else ''
v2v = v2[i] if i < len(v2) else ''
ret += '\t%s, %s\n' % (v1v, v2v)
return ret
else:
return '\t%s\t%s\n' % (v1, v2)
elif isinstance(var, dict):
ret = ''
for key, value in var.iteritems():
# fix this crap, it's not printing all recursive levels of keys!
ret += '%s %s' % (key, convertToTable(value))
return ret
else:
return '%s\n' % (var)
I don´t know how to pass the previous keys recursively to the function again! Either I get an extra print of keys or nothing! (please do not advice me that I should use json.dumps
as it does not really do what I need!)
I am hoping someone can check my solution and point out the flaw in it!
I'm not sure what's wrong with your code, but this might do what you want:
def iteritems_recursive(d):
for k,v in d.iteritems():
if isinstance(v, dict):
for k1,v1 in iteritems_recursive(v):
yield (k,)+k1, v1
else:
yield (k,),v
dic = {u'resources': {u'info': {u'load': (u'37', u'17')}, u'peak': {u'load': (u'0', u'1')}}}
for p,v in iteritems_recursive(dic):
print p, "->", v
iteritems_recursive
iterates over the passed-in dictionary, and returns a a (path, value)
tuple. The path
is itself a tuple which describes the keys that reach that item.
The above code prints:
(u'resources', u'info', u'load') -> (u'37', u'17')
(u'resources', u'peak', u'load') -> (u'0', u'1')
If you want to print the table pretty, replace the for loop above with this:
for p,v in iteritems_recursive(dic):
diff = float(v[0]) - float(v[1])
p = ''.join('{:10}'.format(w) for w in p)
v = ''.join('{:5}'.format(f) for f in v)
print p, v, diff
Which prints:
resources info load 37 17 20.0
resources peak load 0 1 -1.0
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With