关于python:人类可读的打印字典(JSON)

Printing dictionaries (JSON) human readable

假设我有这样的(嵌套)字典(注意列表值):

1
2
3
4
5
6
7
8
9
dic = {'level1':
            {'level2':(1, 2),
             'level3':
                    [
                     {'level4': (1, 2)},
                     {'level5': (1, 2)}
                    ]
             }
       }

我正在寻找一种正确的方法来打印这本词典,我正在使用json来执行此操作:

1
2
import json
print json.dumps(dic, indent=4)

上面的代码给出了以下输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
   "level1": {
       "level2": [
            1,
            2
        ],
       "level3": [
            {
               "level4": [
                    1,
                    2
                ]
            },
            {
               "level5": [
                    1,
                    2
                ]
            }
        ]
    }
}

虽然上面的输出相当好,但是仍然很难读取,特别是如果有许多级别和更长的名称。我也试过了。

1
2
import yaml
print yaml.dump(dic)

给出以下看起来很奇怪的信息:

1
2
3
4
5
level1:
  level2: !!python/tuple [1, 2]
  level3:
  - level4: !!python/tuple [1, 2]
  - level5: !!python/tuple [1, 2]

是否有其他库可以生成更好的转储,我认为下面的输出更容易阅读:

1
2
3
4
5
"level1"
    |---"level2":            1, 2
    |---"level3":
            |---"level4":    1, 2
            |---"level5":    1, 2

我相信上面的内容更容易阅读,而且可能有一些Python库可以做到这一点。


这是根据ActiveState代码示例改编的。不能说它很漂亮,但可能会让你朝着正确的方向前进:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
myDict = {'level1':
         {'level2':(1, 2),
          'level3':
                [
                 {'level4': (1, 2)},
                 {'level5': (1, 2)},
                ],
         'level6': [1,2,3],
         'level7':{'level8': (1,2), 'level9': (1,2)}
         }
    }



def prettyPrint(dictionary, ident = '', braces=1):
    for key, value in dictionary.iteritems():
        if isinstance(value, dict):
            print '%s%s%s%s' % (ident, braces*'[', key, braces*']')
            prettyPrint(value, ident+'  ', braces+1)
        elif isinstance(value, list):
            ndict=0
            for v in value:
                if isinstance(v, dict):
                    ndict += 1
            if ndict:
                print '%s%s' % (ident, key)
                for e in value:
                    if isinstance(e, dict):
                        prettyPrint(e, ident+'  ', braces+1)
                    else:
                         print ident+'%s : %s' %(key, e)
            else:
                print ident+'%s : %s' %(key, value)
        else:
            print ident+'%s : %s' %(key, value)

prettyPrint(myDict)


[level1]
  level2 : (1, 2)
  level3
    level4 : (1, 2)
    level5 : (1, 2)
  level6 : [1, 2, 3]
  [[level7]]
    level8 : (1, 2)
    level9 : (1, 2)