如何漂亮地打印嵌套字典?

2025-01-21 09:01:00
admin
原创
87
摘要:问题描述:如何在 Python 中漂亮地打印深度约为 4 的字典?我尝试使用 进行漂亮打印pprint(),但没有成功:import pprint pp = pprint.PrettyPrinter(indent=4) pp.pprint(mydict) 我只是想要" "每个嵌套都...

问题描述:

如何在 Python 中漂亮地打印深度约为 4 的字典?我尝试使用 进行漂亮打印pprint(),但没有成功:

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

我只是想要" "每个嵌套都有一个缩进(),这样我就可以得到如下内容:

key1
    value1
    value2
    key2
       value1
       value2

ETC。

我怎样才能做到这一点?


解决方案 1:

我的第一个想法是 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
        }
    }
}

解决方案 2:

我不确定你到底想要什么样的格式,但你可以从这样的函数开始:

def pretty(d, indent=0):
   for key, value in d.items():
      print('    ' * indent + str(key))
      if isinstance(value, dict):
         pretty(value, indent+1)
      else:
         print('    ' * (indent+1) + str(value))

解决方案 3:

您可以通过PyYAML尝试YAML。其输出可以进行微调。我建议从以下内容开始:

print(yaml.dump(data, allow_unicode=True, default_flow_style=False))

结果非常易读;如果需要,也可以将其解析回 Python。

编辑:

例子:

>>> import yaml
>>> data = {'a':2, 'b':{'x':3, 'y':{'t1': 4, 't2':5}}}
>>> print(yaml.dump(data, default_flow_style=False))
a: 2
b:
  x: 3
  y:
    t1: 4
    t2: 5

解决方案 4:

其中最具 Python 特色的方法就是使用已经构建的pprint模块。

定义打印深度所需的参数正如您所期望的depth

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

就是这样 !

解决方案 5:

通过这种方式,您可以以漂亮的方式打印它,例如您的词典名称是yasin

import json

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

或者更安全:

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

解决方案 6:

就目前所做的工作而言,我没有看到任何漂亮的打印机至少可以以非常简单的格式模仿 Python 解释器的输出,所以这是我的:

class Formatter(object):
    def __init__(self):
        self.types = {}
        self.htchar = '    '
        self.lfchar = '
'
        self.indent = 0
        self.set_formater(object, self.__class__.format_object)
        self.set_formater(dict, self.__class__.format_dict)
        self.set_formater(list, self.__class__.format_list)
        self.set_formater(tuple, self.__class__.format_tuple)

    def set_formater(self, obj, callback):
        self.types[obj] = callback

    def __call__(self, value, **args):
        for key in args:
            setattr(self, key, args[key])
        formater = self.types[type(value) if type(value) in self.types else object]
        return formater(self, value, self.indent)

    def format_object(self, value, indent):
        return repr(value)

    def format_dict(self, value, indent):
        items = [
            self.lfchar + self.htchar * (indent + 1) + repr(key) + ': ' +
            (self.types[type(value[key]) if type(value[key]) in self.types else object])(self, value[key], indent + 1)
            for key in value
        ]
        return '{%s}' % (','.join(items) + self.lfchar + self.htchar * indent)

    def format_list(self, value, indent):
        items = [
            self.lfchar + self.htchar * (indent + 1) + (self.types[type(item) if type(item) in self.types else object])(self, item, indent + 1)
            for item in value
        ]
        return '[%s]' % (','.join(items) + self.lfchar + self.htchar * indent)

    def format_tuple(self, value, indent):
        items = [
            self.lfchar + self.htchar * (indent + 1) + (self.types[type(item) if type(item) in self.types else object])(self, item, indent + 1)
            for item in value
        ]
        return '(%s)' % (','.join(items) + self.lfchar + self.htchar * indent)

初始化它:

pretty = Formatter()

它可以支持为定义的类型添加格式化程序,您只需为其创建一个像这样的函数,然后使用 set_formater 将其绑定到您想要的类型:

from collections import OrderedDict

def format_ordereddict(self, value, indent):
    items = [
        self.lfchar + self.htchar * (indent + 1) +
        "(" + repr(key) + ', ' + (self.types[
            type(value[key]) if type(value[key]) in self.types else object
        ])(self, value[key], indent + 1) + ")"
        for key in value
    ]
    return 'OrderedDict([%s])' % (','.join(items) +
           self.lfchar + self.htchar * indent)
pretty.set_formater(OrderedDict, format_ordereddict)

由于历史原因,我保留了以前的漂亮打印机,它是一个函数而不是一个类,但它们都可以以相同的方式使用,类版本只是允许更多:

def pretty(value, htchar='    ', lfchar='
', indent=0):
    nlch = lfchar + htchar * (indent + 1)
    if type(value) is dict:
        items = [
            nlch + repr(key) + ': ' + pretty(value[key], htchar, lfchar, indent + 1)
            for key in value
        ]
        return '{%s}' % (','.join(items) + lfchar + htchar * indent)
    elif type(value) is list:
        items = [
            nlch + pretty(item, htchar, lfchar, indent + 1)
            for item in value
        ]
        return '[%s]' % (','.join(items) + lfchar + htchar * indent)
    elif type(value) is tuple:
        items = [
            nlch + pretty(item, htchar, lfchar, indent + 1)
            for item in value
        ]
        return '(%s)' % (','.join(items) + lfchar + htchar * indent)
    else:
        return repr(value)

使用方法:

>>> a = {'list':['a','b',1,2],'dict':{'a':1,2:'b'},'tuple':('a','b',1,2),'function':pretty,'unicode':u'xa7',("tuple","key"):"valid"}
>>> a
{'function': <function pretty at 0x7fdf555809b0>, 'tuple': ('a', 'b', 1, 2), 'list': ['a', 'b', 1, 2], 'dict': {'a': 1, 2: 'b'}, 'unicode': u'xa7', ('tuple', 'key'): 'valid'}
>>> print(pretty(a))
{
    'function': <function pretty at 0x7fdf555809b0>,
    'tuple': (
        'a',
        'b',
        1,
        2
    ),
    'list': [
        'a',
        'b',
        1,
        2
    ],
    'dict': {
        'a': 1,
        2: 'b'
    },
    'unicode': u'xa7',
    ('tuple', 'key'): 'valid'
}

与其他版本相比:

  • 该解决方案直接查找对象类型,因此您可以漂亮地打印几乎所有内容,而不仅仅是列表或字典。

  • 没有任何依赖性。

  • 所有内容都放在字符串中,因此你可以用它做任何你想做的事情。

  • 该类和函数已经过测试并且适用于 Python 2.7 和 3.4。

  • 您可以拥有所有类型的对象,这是它们的表示形式,而不是放入结果中的内容(因此字符串有引号,Unicode 字符串得到完整表示...)。

  • 使用类版本,您可以为所需的每个对象类型添加格式,或将其更改为已定义的格式。

  • key 可以是任何有效类型。

  • 缩进和换行符可以根据我们的需要进行更改。

  • 字典、列表和元组都打印得很漂亮。

解决方案 7:

这里的现代解决方案是使用rich。使用以下方式安装

pip install rich

并使用

from rich import print

d = {
    "Alabama": "Montgomery",
    "Alaska": "Juneau",
    "Arizona": "Phoenix",
    "Arkansas": "Little Rock",
    "California": "Sacramento",
    "Colorado": "Denver",
    "Connecticut": "Hartford",
    "Delaware": "Dover",
    "Florida": "Tallahassee",
    "Georgia": "Atlanta",
    "Hawaii": "Honolulu",
    "Idaho": "Boise",
}
print(d)

输出缩进得很好:

在此处输入图片描述

解决方案 8:

default我还必须传递参数,如下所示:

print(json.dumps(my_dictionary, indent=4, default=str))

如果您希望对键进行排序,那么您可以执行以下操作:

print(json.dumps(my_dictionary, sort_keys=True, indent=4, default=str))

为了修复这种类型的错误:

TypeError: Object of type 'datetime' is not JSON serializable

这是因为日期时间是字典中的某些值。

解决方案 9:

另一个选择是yapf

from pprint import pformat
from yapf.yapflib.yapf_api import FormatCode

dict_example = {'1': '1', '2': '2', '3': [1, 2, 3, 4, 5], '4': {'1': '1', '2': '2', '3': [1, 2, 3, 4, 5]}}
dict_string = pformat(dict_example)
formatted_code, _ = FormatCode(dict_string)

print(formatted_code)

输出:

{
    '1': '1',
    '2': '2',
    '3': [1, 2, 3, 4, 5],
    '4': {
        '1': '1',
        '2': '2',
        '3': [1, 2, 3, 4, 5]
    }
}

解决方案 10:

您可以使用print-dict

from print_dict import pd

dict1 = {
    'key': 'value'
} 

pd(dict1)

输出:

{
    'key': 'value'
}

该Python 代码的输出:

{
    'one': 'value-one',
    'two': 'value-two',
    'three': 'value-three',
    'four': {
        '1': '1',
        '2': '2',
        '3': [1, 2, 3, 4, 5],
        '4': {
            'method': <function custom_method at 0x7ff6ecd03e18>,
            'tuple': (1, 2),
            'unicode': '✓',
            'ten': 'value-ten',
            'eleven': 'value-eleven',
            '3': [1, 2, 3, 4]
        }
    },
    'object1': <__main__.Object1 object at 0x7ff6ecc588d0>,
    'object2': <Object2 info>,
    'class': <class '__main__.Object1'>
}

安装:

$ pip install print-dict

披露:我是print-dict

解决方案 11:

我尝试了以下并得到了我想要的结果

方法 1:

步骤 1:print_dict通过输入以下命令进行安装cmd

pip install print_dict

步骤 2:导入 print_dict 作为

from print_dict import pd

步骤 3:使用pd

pd(your_dictionary_name)

示例输出:

{
    'Name': 'Arham Rumi',
    'Age': 21,
    'Movies': ['adas', 'adfas', 'fgfg', 'gfgf', 'vbxbv'],
    'Songs': ['sdfsd', 'dfdgfddf', 'dsdfd', 'sddfsd', 'sdfdsdf']
}

方法 2:

我们还可以使用for循环打印字典,items方法如下

for key, Value in your_dictionary_name.items():
    print(f"{key} : {Value}")

解决方案 12:

正如其他人所发布的,您可以使用 recursion/dfs 来打印嵌套字典数据,如果它是字典,则递归调用;否则打印数据。

def print_json(data):
    if type(data) == dict:
            for k, v in data.items():
                    print k
                    print_json(v)
    else:
            print data

解决方案 13:

pout可以漂亮地打印您向其抛出的任何内容,例如(借用data另一个答案):

data = {'a':2, 'b':{'x':3, 'y':{'t1': 4, 't2':5}}}
pout.vs(data)

将导致在屏幕上打印如下输出:

{
    'a': 2,
    'b':
    {
        'y':
        {
            't2': 5,
            't1': 4
        },
        'x': 3
    }
}

或者您可以返回对象的格式化字符串输出:

v = pout.s(data)

它的主要用例是进行调试,因此它不会阻塞对象实例或任何东西,并且它会按照您期望的方式处理unicode输出,适用于python 2.7和3。

披露:我是 pout 的作者和维护者。

解决方案 14:

prettyformatter

免责声明:我是该软件包的作者。

要与其他格式化程序进行比较,请参阅其他格式化程序。


格式化

与 不同pprint.pprintprettyformatter它会垂直扩展更多,并尝试使项目更加对齐。

与不同json.dumpsprettyformatter通常更紧凑并尝试在合理的地方对齐字典值。

from prettyformatter import pprint

batters = [
    {"id": "1001", "type": "Regular"},
    {"id": "1002", "type": "Chocolate"},
    {"id": "1003", "type": "Blueberry"},
    {"id": "1004", "type": "Devil's Food"},
]

toppings = [
    {"id": "5001", "type": None},
    {"id": "5002", "type": "Glazed"},
    {"id": "5005", "type": "Sugar"},
    {"id": "5007", "type": "Powdered Sugar"},
    {"id": "5006", "type": "Chocolate with Sprinkles"},
    {"id": "5003", "type": "Chocolate"},
    {"id": "5004", "type": "Maple"},
]

data = {"id": "0001", "type": "donut", "name": "Cake", "ppu": 0.55, "batters": batters, "topping": toppings}

pprint(data)

输出:

{
    "id"    : "0001",
    "type"  : "donut",
    "name"  : "Cake",
    "ppu"   : 0.55,
    "batters":
        [
            {"id": "1001", "type": "Regular"},
            {"id": "1002", "type": "Chocolate"},
            {"id": "1003", "type": "Blueberry"},
            {"id": "1004", "type": "Devil's Food"},
        ],
    "topping":
        [
            {"id": "5001", "type": None},
            {"id": "5002", "type": "Glazed"},
            {"id": "5005", "type": "Sugar"},
            {"id": "5007", "type": "Powdered Sugar"},
            {"id": "5006", "type": "Chocolate with Sprinkles"},
            {"id": "5003", "type": "Chocolate"},
            {"id": "5004", "type": "Maple"},
        ],
}

特征

请参阅此处查看完整文档。

JSON

与 不同pprint.pprintprettyformatter支持通过参数进行 JSON 转换json=True。这包括更改为Nonenull、以及正确使用引号。True`trueFalsefalse`

与 不同json.dumpsprettyformatter支持更多数据类型的 JSON 强制转换。这包括将 anydataclassmapping更改为 adict以及将 anyiterable更改为 a list

from dataclasses import dataclass

from prettyformatter import PrettyDataclass, pprint


@dataclass(unsafe_hash=True)
class Point(PrettyDataclass):
    x: int
    y: int


pprint((Point(1, 2), Point(3, 4)), json=True)

输出:

[{"x": 1, "y": 2}, {"x": 3, "y": 4}]

定制

pprint.pprint或不同json.dumpsprettyformatter支持通过附加类型轻松定制。

为子类实现__pargs__and/or方法允许人们轻松地以 的形式定制类。__pkwargs__`prettyformatter.PrettyClass`"cls_name(*args, **kwargs)"

from prettyformatter import PrettyClass


class Dog(PrettyClass):

    def __init__(self, name, **kwargs):
        self.name = name

    def __pkwargs__(self):
        return {"name": self.name}


print(Dog("Fido"))
"""
Dog(name="Fido")
"""

print(Dog("Fido"), json=True)
"""
{"name": "Fido"}
"""

实现该__pformat__方法可以实现更具体的pformat功能。

实现该@prettyformatter.register函数还允许以相同的方式定制已经存在的类__pformat__

import numpy as np
from prettyformatter import pprint, register

@register(np.ndarray)
def pformat_ndarray(obj, specifier, depth, indent, shorten, json):
    if json:
        return pformat(obj.tolist(), specifier, depth, indent, shorten, json)
    with np.printoptions(formatter=dict(all=lambda x: format(x, specifier))):
        return repr(obj).replace("
", "
" + " " * depth)

pprint(dict.fromkeys("ABC", np.arange(9).reshape(3, 3)))

输出:

{
    "A":
        array([[0, 1, 2],
               [3, 4, 5],
               [6, 7, 8]]),
    "B":
        array([[0, 1, 2],
               [3, 4, 5],
               [6, 7, 8]]),
    "C":
        array([[0, 1, 2],
               [3, 4, 5],
               [6, 7, 8]]),
}

解决方案 15:

我接受了某人的答案并对其进行了稍微的修改以满足我对嵌套字典和列表的需求:

def pretty(d, indent=0):
    if isinstance(d, dict):
        for key, value in d.iteritems():
            print '    ' * indent + str(key)
            if isinstance(value, dict) or isinstance(value, list):
                pretty(value, indent+1)
            else:
                print '    ' * (indent+1) + str(value)
    elif isinstance(d, list):
        for item in d:
            if isinstance(item, dict) or isinstance(item, list):
                pretty(item, indent+1)
            else:
                print '    ' * (indent+1) + str(item)
    else:
        pass

然后它给出如下输出:

>>> 
xs:schema
    @xmlns:xs
        http://www.w3.org/2001/XMLSchema
    xs:redefine
        @schemaLocation
            base.xsd
        xs:complexType
            @name
                Extension
            xs:complexContent
                xs:restriction
                    @base
                        Extension
                    xs:sequence
                        xs:element
                            @name
                                Policy
                            @minOccurs
                                1
                            xs:complexType
                                xs:sequence
                                    xs:element
                                            ...

解决方案 16:

我利用了你们教给我的知识以及装饰器的力量来重载经典的打印函数。只需根据需要更改缩进即可。我将其作为要点添加到github 中,以防您想为其加注星标(保存)。

def print_decorator(func):
    """
    Overload Print function to pretty print Dictionaries 
    """
    def wrapped_func(*args,**kwargs):
        if isinstance(*args, dict):
            return func(json.dumps(*args, sort_keys=True, indent=2, default=str))
        else:
            return func(*args,**kwargs)
    return wrapped_func
print = print_decorator(print)

现在只需照常使用打印即可。

解决方案 17:

嗯,我觉得那很漂亮 ;)

def pretty(d, indent=0):
    for key, value in d.iteritems():
        if isinstance(value, dict):
            print '    ' * indent + (("%30s: {
") % str(key).upper())
            pretty(value, indent+1)
            print '    ' * indent + ' ' * 32 + ('} # end of %s #
' % str(key).upper())
        elif isinstance(value, list):
            for val in value:
                print '    ' * indent + (("%30s: [
") % str(key).upper())
                pretty(val, indent+1)
                print '    ' * indent + ' ' * 32 + ('] # end of %s #
' % str(key).upper())
        else:
            print '    ' * indent + (("%30s: %s") % (str(key).upper(),str(value)))

解决方案 18:

我编写了这个简单的代码来在 Python 中打印 json 对象的一般结构。

def getstructure(data, tab = 0):
    if type(data) is dict:
        print ' '*tab + '{' 
        for key in data:
            print ' '*tab + '  ' + key + ':'
            getstructure(data[key], tab+4)
        print ' '*tab + '}'         
    elif type(data) is list and len(data) > 0:
        print ' '*tab + '['
        getstructure(data[0], tab+4)
        print ' '*tab + '  ...'
        print ' '*tab + ']'

以下数据的结果

a = {'list':['a','b',1,2],'dict':{'a':1,2:'b'},'tuple':('a','b',1,2),'function':'p','unicode':u'xa7',("tuple","key"):"valid"}
getstructure(a)

非常紧凑,如下所示:

{
  function:
  tuple:
  list:
    [
      ...
    ]
  dict:
    {
      a:
      2:
    }
  unicode:
  ('tuple', 'key'):
}

解决方案 19:

我只是在采纳了sth的答案并做了一个小但非常有用的修改后才回到这个问题。此函数打印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']因为格式化为字符串的值的长度非常大。

解决方案 20:

最简单的方法是安装 IPython 并使用下面类似的方法

from IPython.lib.pretty import pretty


class MyClass:
    __repr__(self):
       return pretty(data)  # replace data with what makes sense

在你的情况下

print(pretty(mydict))

解决方案 21:

虽然有点晚了,但这个答案不需要任何额外的库。与 STH 的答案类似,但格式更强大一些,并返回一个可以打印的完整字符串:

def pretty_print_dict(
        input_dictionary,
        indent=1,
        depth=0
):
    # Bool flag to add comma's after first item in dict.
    needs_comma = False
    # String for any dict will start with a '{'
    return_string = '    ' * depth + '{
'
    # Iterate over keys and values, building the full string out.
    for key, value in input_dictionary.items():
        # Start with key. If key follows a previous item, add comma.
        if needs_comma:
            return_string = return_string + ',
' + '    ' * (depth + 1) + str(key) + ': '
        else:
            return_string = return_string + '    ' * (depth + 1) + str(key) + ': '
        # If the value is a dict, recursively call function.
        if isinstance(value, dict):
            return_string = return_string + '
' + pretty_print_dict(value, depth=depth+2)
        else:
            return_string = return_string + '    ' * indent + str(value)
        # After first line, flip bool to True to make sure commas make it.
        needs_comma = True
    # Complete the dict with a '}'
    return_string = return_string + '
' + '    ' * depth + '}'
    # Return dict string.
    return return_string

让我们看看它如何处理像这样的字典test_dict={1: 2, 3: {4: {5: 6}, 7: 8}, 9: 10}

该字符串如下所示:`'{

1:     2,
3: 
    {
        4: 
            {
                5:     6
            },
        7:     8
    },
9:     10

}'`。

打印该字符串得到:

{
    1:  2,
    3: 
        {
            4: 
                {
                    5:  6
                },
            7:  8
        },
    9:  10
}

解决方案 22:

This class prints out a complex nested dictionary with sub dictionaries and sub lists.  
##
## Recursive class to parse and print complex nested dictionary
##

class NestedDictionary(object):
    def __init__(self,value):
        self.value=value

    def print(self,depth):
        spacer="--------------------"
        if type(self.value)==type(dict()):
            for kk, vv in self.value.items():
                if (type(vv)==type(dict())):
                    print(spacer[:depth],kk)
                    vvv=(NestedDictionary(vv))
                    depth=depth+3
                    vvv.print(depth)
                    depth=depth-3
                else:
                    if (type(vv)==type(list())):
                        for i in vv:
                            vvv=(NestedDictionary(i))
                            depth=depth+3
                            vvv.print(depth)
                            depth=depth-3
                    else:
                        print(spacer[:depth],kk,vv) 

##
## Instatiate and execute - this prints complex nested dictionaries
## with sub dictionaries and sub lists
## 'something' is a complex nested dictionary

MyNest=NestedDictionary(weather_com_result)
MyNest.print(0)

解决方案 23:

这里有很多不错的实现,这让我想添加自己的实现 :)。我用它在 CircuitPython 和 MicroPython 中进行调试,因为json.dumps不允许使用indent参数,并且pprint也不可用。

它是用自身实现的,因此可以放入类中,并且对于每个数据,它都会显示数据类型,我发现这对于调试非常有用。不依赖于任何外部模块。

def pretty_print_dict(self, d, indent=0):
    INDENT = 2
    if isinstance(d, dict):
        print(' ' * indent + '{')
        for key, value in d.items():
            print(f'{" " * (indent + INDENT)}{key}:')
            self.pretty_print_dict(value, indent + 2 * INDENT)
        print(' ' * indent + '}')
    elif isinstance(d, list):
        print(' ' * indent + '[')
        for item in d:
            self.pretty_print_dict(item, indent + INDENT)
        print(' ' * indent + ']')
    elif isinstance(d, str):
        print(' ' * indent + '<s>' + d + '</s>')
    elif isinstance(d, int):
        print(' ' * indent + '<i>' + str(d) + '</i>')
    elif isinstance(d, bool):
        print(' ' * indent + '<b>' + str(d) + '</b>')
    elif isinstance(d, float):
        print(' ' * indent + '<f>' + str(d) + '</f>')
    else:
        print(' ' * indent + '<?>' + str(d) + '</?>')

用法:self.pretty_print_dict(my_dict)

解决方案 24:

我自己是一个相对的 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.`]]

这种方法的优点是缩进量正好是 堆栈长度的倍数:

indent = "    " * 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模块会以一种良好的格式打印嵌套字典。

解决方案 25:

这是我根据 sth 的注释编写的一个函数。它与带缩进的 json.dumps 工作原理相同,但我使用制表符而不是空格来缩进。在 Python 3.2+ 中,您可以直接将缩进指定为 '\t',但在 2.7 中则不行。

def pretty_dict(d):
    def pretty(d, indent):
        for i, (key, value) in enumerate(d.iteritems()):
            if isinstance(value, dict):
                print '{0}"{1}": {{'.format( '    ' * indent, str(key))
                pretty(value, indent+1)
                if i == len(d)-1:
                    print '{0}}}'.format( '    ' * indent)
                else:
                    print '{0}}},'.format( '    ' * indent)
            else:
                if i == len(d)-1:
                    print '{0}"{1}": "{2}"'.format( '    ' * indent, str(key), value)
                else:
                    print '{0}"{1}": "{2}",'.format( '    ' * indent, str(key), value)
    print '{'
    pretty(d,indent=1)
    print '}'

前任:

>>> dict_var = {'a':2, 'b':{'x':3, 'y':{'t1': 4, 't2':5}}}
>>> pretty_dict(dict_var)
{
    "a": "2",
    "b": {
        "y": {
            "t2": "5",
            "t1": "4"
        },
        "x": "3"
    }
}

解决方案 26:

这里可以打印任何类型的嵌套字典,同时跟踪其“父”字典。

dicList = list()

def prettierPrint(dic, dicList):
count = 0
for key, value in dic.iteritems():
    count+=1
    if str(value) == 'OrderedDict()':
        value = None
    if not isinstance(value, dict):
        print str(key) + ": " + str(value)
        print str(key) + ' was found in the following path:',
        print dicList
        print '
'
    elif isinstance(value, dict):
        dicList.append(key)
        prettierPrint(value, dicList)
    if dicList:
         if count == len(dic):
             dicList.pop()
             count = 0

prettierPrint(dicExample, dicList)

这是根据不同格式(如 OP 中指定的格式)进行打印的一个很好的起点。您真正需要做的只是围绕Print块进行操作。请注意,它会查看值是否为“OrderedDict()”。根据您是否正在使用Container datatypes Collections中的某些内容,您应该制作这些类型的故障保护,以便elif块不会因其名称而将其视为附加字典。截至目前,一个示例字典如下

example_dict = {'key1': 'value1',
            'key2': 'value2',
            'key3': {'key3a': 'value3a'},
            'key4': {'key4a': {'key4aa': 'value4aa',
                               'key4ab': 'value4ab',
                               'key4ac': 'value4ac'},
                     'key4b': 'value4b'}

将打印

key3a: value3a
key3a was found in the following path: ['key3']

key2: value2
key2 was found in the following path: []

key1: value1
key1 was found in the following path: []

key4ab: value4ab
key4ab was found in the following path: ['key4', 'key4a']

key4ac: value4ac
key4ac was found in the following path: ['key4', 'key4a']

key4aa: value4aa
key4aa was found in the following path: ['key4', 'key4a']

key4b: value4b
key4b was found in the following path: ['key4']

~修改代码以适应问题的格式~

lastDict = list()
dicList = list()
def prettierPrint(dic, dicList):
    global lastDict
    count = 0
    for key, value in dic.iteritems():
        count+=1
        if str(value) == 'OrderedDict()':
            value = None
        if not isinstance(value, dict):
            if lastDict == dicList:
                sameParents = True
            else:
                sameParents = False

            if dicList and sameParents is not True:
                spacing = ' ' * len(str(dicList))
                print dicList
                print spacing,
                print str(value)

            if dicList and sameParents is True:
                print spacing,
                print str(value)
            lastDict = list(dicList)

        elif isinstance(value, dict):
            dicList.append(key)
            prettierPrint(value, dicList)

        if dicList:
             if count == len(dic):
                 dicList.pop()
                 count = 0

使用相同的示例代码,它将打印以下内容:

['key3']
         value3a
['key4', 'key4a']
                  value4ab
                  value4ac
                  value4aa
['key4']
         value4b

这并不是OP 中要求的。不同之处在于,parent^n 仍会打印,而不是缺失并替换为空格。要获得 OP 的格式,您需要执行以下操作:迭代地将 dicList 与 lastDict 进行比较可以通过创建一个新字典并将 dicList 的内容复制到其中来做到这一点,检查复制字典中的i是否与 lastDict 中的i相同,如果相同,则使用字符串乘数函数将空格写入该i位置。

解决方案 27:

使用此功能:

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)

解决方案 28:

这是我在处理需要在 .txt 文件中写入字典的课程时想到的:

@staticmethod
def _pretty_write_dict(dictionary):

    def _nested(obj, level=1):
        indentation_values = "    " * level
        indentation_braces = "    " * (level - 1)
        if isinstance(obj, dict):
            return "{
%(body)s%(indent_braces)s}" % {
                "body": "".join("%(indent_values)s\'%(key)s\': %(value)s,
" % {
                    "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 "[
%(body)s
%(indent_braces)s]" % {
                "body": "".join("%(indent_values)s%(value)s,
" % {
                    "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': '',
    },
}

解决方案 29:

这是从字典或列表创建格式化的字符串:

def pretty(d, indent=0):
    result = ""
    if isinstance(d, dict):
        for key, value in d.items():
            result += "    " * indent + str(key) + "
"
            if isinstance(value, (dict, list, tuple)):
                result += pretty(value, indent + 1)
            else:
                result += "    " * (indent + 1) + str(value) + "
"
    elif isinstance(d, (list, tuple)):
        for item in d:
            if isinstance(item, (dict, list, tuple)):
                result += pretty(item, indent + 1)
            else:
                result += "    " * indent + str(item) + "
"
    else:
        result += "    " * indent + str(d) + "
"
    return result
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1579  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1355  
  信创产品在政府采购中的占比分析随着信息技术的飞速发展以及国家对信息安全重视程度的不断提高,信创产业应运而生并迅速崛起。信创,即信息技术应用创新,旨在实现信息技术领域的自主可控,减少对国外技术的依赖,保障国家信息安全。政府采购作为推动信创产业发展的重要力量,其对信创产品的采购占比情况备受关注。这不仅关系到信创产业的发展前...
信创和国产化的区别   8  
  信创,即信息技术应用创新产业,旨在实现信息技术领域的自主可控,摆脱对国外技术的依赖。近年来,国货国用信创发展势头迅猛,在诸多领域取得了显著成果。这一发展趋势对科技创新产生了深远的推动作用,不仅提升了我国在信息技术领域的自主创新能力,还为经济社会的数字化转型提供了坚实支撑。信创推动核心技术突破信创产业的发展促使企业和科研...
信创工作   9  
  信创技术,即信息技术应用创新产业,旨在实现信息技术领域的自主可控与安全可靠。近年来,信创技术发展迅猛,对中小企业产生了深远的影响,带来了诸多不可忽视的价值。在数字化转型的浪潮中,中小企业面临着激烈的市场竞争和复杂多变的环境,信创技术的出现为它们提供了新的发展机遇和支撑。信创技术对中小企业的影响技术架构变革信创技术促使中...
信创国产化   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用