递归遍历字典
我需要递归地遍历一个字典,并且记住之前的键。
让我来解释一下:
dic = {u'resources': {u'info': {u'load': (u'37', u'17')}}, u'peak': {u'load': (u'0', u'1')}}
这些元素要么是一个值,要么是一个字典,直到遇到一个值为止。我想把上面的 dic
打印成这样:(下面的 xxx 可以省略,最终应该是两个值的差异)
resources info load 37 17 xxx
resources peak load 0 1 xxx
这是我目前写的代码:
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)
我不知道怎么把之前的键递归地传回函数里!要么我会多打印一些键,要么什么都不打印!(请不要建议我使用 json.dumps
,因为它并不能满足我的需求!)我希望有人能检查一下我的解决方案,并指出其中的错误!
3 个回答
我有两个解决方案,第一个方案是在每一层都把所有的键名都记录下来,然后在最后的时候把它们打印出来,再返回到上层。
第二个方案是在下去的过程中直接打印这些键名,这样就不用去“记住”每一层的内容了。
import sys
dic = {u'resources':
{u'info':
{u'load': (u'37', u'17')}
},
u'peak':
{u'load': (u'0', u'1')}
}
def racecar(goomba, levels=None):
if levels == None:
levels = []
for key in goomba:
if type(goomba[key]) is dict:
levels.append(key)
levels = racecar(goomba[key], levels)
else:
levels.append(key)
for name in levels:
sys.stdout.write(name + ' ')
for val in goomba[key]:
sys.stdout.write(val + ' ')
sys.stdout.write('xxx\n')
return []
def racecar2(goomba):
for key in goomba:
sys.stdout.write(key + ' ')
if type(goomba[key]) is dict:
racecar(goomba[key])
else:
for val in goomba[key]:
sys.stdout.write(val + ' ')
sys.stdout.write('xxx\n')
racecar(dic)
racecar2(dic)
返回结果:
peak load 0 1 xxx
resources info load 37 17 xxx
在编程中,有时候我们会遇到一些问题,比如代码运行不正常或者出现错误。这个时候,我们可以去一些技术论坛,比如StackOverflow,寻求帮助。在这些论坛上,很多人会分享他们的经验和解决方案。
例如,有人可能会问:“我在运行我的程序时,为什么总是出现这个错误?”然后,其他人就会根据他们的经验来回答,提供一些建议或者解决办法。
在这些讨论中,大家会用一些代码示例来说明问题,这样更容易让人理解。比如,他们可能会贴出一段代码,说明在什么情况下会出现错误,或者如何修改代码来解决问题。
总之,技术论坛是一个很好的地方,可以让我们学习到很多知识,解决我们在编程过程中遇到的各种问题。
def convertToTable(inp, history=[]):
for key, value in inp.iteritems():
history.append(key)
if type(value) == dict:
convertToTable(value, history)
else:
print '{} {} {}'.format(' -> '.join(history), value[0], value[1])
history.pop()
dic = {'peak': {'load': ('0', '1'), 'unload': ('2', '3')}, 'resources': {'info': {'loadxx': ('37', '17')}}}
convertToTable(dic)
# peak -> load 0 1
# peak -> unload 2 3
# resources -> info -> loadxx 37 17
我不太确定你的代码哪里出问题了,但这个可能能满足你的需求:
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
这个函数会遍历你传入的字典,并返回一个 (路径, 值)
的元组。这里的 路径
本身也是一个元组,用来描述到达那个项目的键。
上面的代码会打印出:
(u'resources', u'info', u'load') -> (u'37', u'17')
(u'resources', u'peak', u'load') -> (u'0', u'1')
如果你想让表格看起来更好看,可以把上面的 for 循环换成这个:
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
这样打印出来的结果是:
resources info load 37 17 20.0
resources peak load 0 1 -1.0