4

辞書を再帰的にトラバースし、前のキーを記憶する必要があります。

説明させてください:

dic = {u'resources': {u'info': {u'load': (u'37', u'17')}}, u'peak': {u'load': (u'0', u'1')}}

値に到達するまで、要素は常に値またはディクショナリです。上記を次のように印刷したいdic: (以下の xxx を省略します。最終的には 2 つの値の差分になります)

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!) 誰かが私のソリューションをチェックして、その欠陥を指摘してくれることを願っています!

4

3 に答える 3

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

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')

テーブルをきれいに印刷したい場合は、上記の 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
于 2013-03-15T16:24:15.120 に答える
2
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
于 2013-03-15T16:24:34.030 に答える
2

私には 2 つの解決策があります。1 つ目は、すべてのキーの名前をレベルに保持し、それらを一番下に出力してからスタックに戻します。

2番目は、レベルを「覚える」必要がないように、途中でそれらを印刷します

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
于 2013-03-15T16:26:22.367 に答える