如何在Python中漂亮地打印深度为~4的字典?我尝试用pprint()进行漂亮的打印,但它不起作用:

import pprint 
pp = pprint.PrettyPrinter(indent=4)
pp.pprint(mydict)

我只是想要一个缩进(“\t”)为每个嵌套,这样我就会得到这样的东西:

key1
    value1
    value2
    key2
       value1
       value2

等。

我该怎么做呢?


当前回答

这是我在编写一个需要在.txt文件中编写字典的类时想到的:

@staticmethod
def _pretty_write_dict(dictionary):

    def _nested(obj, level=1):
        indentation_values = "\t" * level
        indentation_braces = "\t" * (level - 1)
        if isinstance(obj, dict):
            return "{\n%(body)s%(indent_braces)s}" % {
                "body": "".join("%(indent_values)s\'%(key)s\': %(value)s,\n" % {
                    "key": str(key),
                    "value": _nested(value, level + 1),
                    "indent_values": indentation_values
                } for key, value in obj.items()),
                "indent_braces": indentation_braces
            }
        if isinstance(obj, list):
            return "[\n%(body)s\n%(indent_braces)s]" % {
                "body": "".join("%(indent_values)s%(value)s,\n" % {
                    "value": _nested(value, level + 1),
                    "indent_values": indentation_values
                } for value in obj),
                "indent_braces": indentation_braces
            }
        else:
            return "\'%(value)s\'" % {"value": str(obj)}

    dict_text = _nested(dictionary)
    return dict_text

现在,如果我们有一个这样的字典:

some_dict = {'default': {'ENGINE': [1, 2, 3, {'some_key': {'some_other_key': 'some_value'}}], 'NAME': 'some_db_name', 'PORT': '', 'HOST': 'localhost', 'USER': 'some_user_name', 'PASSWORD': 'some_password', 'OPTIONS': {'init_command': 'SET foreign_key_checks = 0;'}}}

我们这样做:

print(_pretty_write_dict(some_dict))

我们得到:

{
    'default': {
        'ENGINE': [
            '1',
            '2',
            '3',
            {
                'some_key': {
                    'some_other_key': 'some_value',
                },
            },
        ],
        'NAME': 'some_db_name',
        'OPTIONS': {
            'init_command': 'SET foreign_key_checks = 0;',
        },
        'HOST': 'localhost',
        'USER': 'some_user_name',
        'PASSWORD': 'some_password',
        'PORT': '',
    },
}

其他回答

我只是在得到某事物的答案并做了一个很小但非常有用的修改之后回到这个问题。该函数打印JSON树中的所有键以及该树中叶节点的大小。

def print_JSON_tree(d, indent=0):
    for key, value in d.iteritems():
        print '    ' * indent + unicode(key),
        if isinstance(value, dict):
            print; print_JSON_tree(value, indent+1)
        else:
            print ":", str(type(d[key])).split("'")[1], "-", str(len(unicode(d[key])))

当您有大型JSON对象并想要找出肉在哪里时,这非常好。例子:

>>> print_JSON_tree(JSON_object)
key1
    value1 : int - 5
    value2 : str - 16
    key2
       value1 : str - 34
       value2 : list - 5623456

这将告诉您,您所关心的大部分数据可能在JSON_object['key1']['key2']['value2']中,因为该值格式化为字符串的长度非常大。

使用这个函数:

def pretty_dict(d, n=1):
    for k in d:
        print(" "*n + k)
        try:
            pretty_dict(d[k], n=n+4)
        except TypeError:
            continue

这样叫它:

pretty_dict(mydict)

我的第一个想法是JSON序列化器可能很擅长嵌套字典,所以我会欺骗并使用它:

>>> import json
>>> print(json.dumps({'a':2, 'b':{'x':3, 'y':{'t1': 4, 't2':5}}},
...                  sort_keys=True, indent=4))
{
    "a": 2,
    "b": {
        "x": 3,
        "y": {
            "t1": 4,
            "t2": 5
        }
    }
}

通过这种方式,你可以打印在漂亮的方式,例如你的字典名字是yasin

import json

print (json.dumps(yasin, indent=2))

或者,更安全:

print (json.dumps(yasin, indent=2, default=str))

我自己是一个相对的python新手,但过去几周我一直在使用嵌套字典,这就是我想到的。

你应该尝试使用堆栈。将根字典中的键变成一个列表的列表:

stack = [ root.keys() ]     # Result: [ [root keys] ]

按照从最后到第一个的相反顺序,查找字典中的每个键,看看它的值是否(也是)一个字典。如果不是,打印密钥,然后删除它。但是,如果键的值是一个字典,则打印该键,然后将该值的键附加到堆栈的末尾,并以相同的方式开始处理该列表,对每个新的键列表进行递归重复。

如果每个列表中第二个键的值是一个字典,那么在几轮之后,你会得到这样的结果:

[['key 1','key 2'],['key 2.1','key 2.2'],['key 2.2.1','key 2.2.2'],[`etc.`]]

这种方法的优点是缩进只是\t乘以堆栈的长度:

indent = "\t" * len(stack)

缺点是为了检查每个键,你需要散列到相关的子字典,尽管这可以通过列表理解和简单的for循环轻松处理:

path = [li[-1] for li in stack]
# The last key of every list of keys in the stack

sub = root
for p in path:
    sub = sub[p]


if type(sub) == dict:
    stack.append(sub.keys()) # And so on

注意,这种方法将要求清除尾随的空列表,并删除后跟空列表的任何列表中的最后一个键(当然,这可能会创建另一个空列表,等等)。

还有其他方法来实现这个方法,但希望这能给你一个基本的想法。

编辑:如果您不想进行所有这些操作,pprint模块将以良好的格式打印嵌套字典。