递归遍历字典

the*_*lse 3 python recursion dictionary python-2.7

我需要递归遍历字典并记住以前的键.

让我解释:

dic = {u'resources': {u'info': {u'load': (u'37', u'17')}}, u'peak': {u'load': (u'0', u'1')}}
Run Code Online (Sandbox Code Playgroud)

元素始终是值或字典,直到达到值.我想打印上面dic这样的:(省略下面的xxx,它最终应该是两个值的差异)

resources info load 37 17 xxx
resources peak load 0 1 xxx
Run Code Online (Sandbox Code Playgroud)

这是我到目前为止的代码:

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)
Run Code Online (Sandbox Code Playgroud)

我不知道如何再次将以前的键递归传递给函数!要么我得到额外的钥匙印刷品或什么都没有!(请不要告诉我,我应该使用json.dumps它,因为它不能真正做我需要的!)我希望有人可以检查我的解决方案,并指出它的缺陷!

Rob*_*obᵩ 5

我不确定你的代码有什么问题,但这可能会做你想要的:

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
Run Code Online (Sandbox Code Playgroud)

iteritems_recursive迭代传入的字典,并返回一个(path, value)元组.该path是本身它描述了到达该项目的键的元组.

上面的代码打印:

(u'resources', u'info', u'load') -> (u'37', u'17')
(u'resources', u'peak', u'load') -> (u'0', u'1')
Run Code Online (Sandbox Code Playgroud)

如果你想打印漂亮的表,用这个替换上面的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
Run Code Online (Sandbox Code Playgroud)

哪个印刷品:

resources info      load       37   17    20.0
resources peak      load       0    1     -1.0
Run Code Online (Sandbox Code Playgroud)