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

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


等。

我该怎么办?

评论

“没用”是什么意思?请非常精确地指定pprint“没有工作”的方式。

我现在使用了以下三个答案(在特定情况下每个答案都不错):@Ken的json答案很好,但是当对象无法json可序列化时有时会失败(抛出异常)。如果@Ken的json答案不起作用,请尝试@Andy的yaml答案,它应该可以工作,但是字符串输出的可读性较差。 [@sth的答案]是最通用的(应该​​适用于任何对象,并且不使用任何库)。

我认为您应该尝试找到合适的width参数。查看说明

#1 楼

我不确定您希望格式看起来如何,但是可以从这样的函数开始:

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


评论


您知道@Ken的常规答案远胜于此。 Json已经处理了所有事情,这可能会产生以下错误:UnicodeEncodeError:'ascii'编解码器无法在位置50编码字符u'\ xf3':序数不在范围内(128)

–为什么
2014年8月27日13:20



我不能使其与我的解决方案的嵌套字典一起使用,因为它给了我UnicodeEncodeError,它也不打印字典键,不进入列表和元组,也不保留python有效语法。

– y.petremann
14-10-6在4:33



这个答案对我来说就像一个魅力,但是我发布了一个新问题stackoverflow.com/questions/36972225/…,该问题设置了应打印多少个值的限制。

– gsamaras
16年5月1日在21:34

非常好。如果您在OP的问题中有嵌套列表,则需要为此添加一些处理。如果您在Py2中遇到问题,这是因为如果没有现在答案中提到的__future__之类的黑客攻击,它就无法正确处理Unicode,因此您必须在需要的地方使用它们(或已更新为3)。

– sudo
18-2-14在18:10



这对我来说足够好:python def pretty(d,indent = 0):对于键,d.items()中的值:if isinstance(value,dict):print(''* * indent + str(key))pretty (value,indent + 1)else:print(''*(indent + 1)+ f“ {key}:{value}”)

– hum3
20-4-27在11:13



#2 楼

我首先想到的是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
        }
    }
}


评论


这很酷,但不能很好地打印所有词典。打印json.dumps(myObject .__ dict__,sort_keys = True,indent = 4)#TypeError:<对象位于0x0000000002E6A748>不能序列化JSON

– tponthieux
2012年2月8日在23:30



尽管这看起来很有用,但它的输出并不是OP想要的。

–马丁内
13年5月24日在3:28

@martineau:OP的请求输出没有意义,字典需要每个值的键。

–naught101
13-10-2在4:28



@ naught101:漂亮的打印机可以执行所需的任何操作以产生所需的输出。

–马丁内
13年10月2日在7:57

json.dumps将转换函数作为可选参数,因此使用json.dumps(myObject .__ dict__,sort_keys = True,indent = 4,deault = str)至少可以使用repr的对象实现来打印自身并弄圆“非JSON可序列化” TypeError

– RFairey
2014年9月23日下午16:20

#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


评论


使用yaml非常有趣,因为它可以保持数据类型的格式不变,我唯一可以反对的是它不会产生有效的python字符串,但是几乎可以转换回python。

– y.petremann
14-10-6在4:49

yaml不喜欢Numpy的标量类型版本...我并不感到惊讶,因为它不支持numpy数组,但是我期望float和numpy.float64具有相同的输出

– PhilMacKay
17 Mar 2 '17 at 17:12

这种方法对我来说也适用于字典列表

–格兰特·香农(Grant Shannon)
20-2-18在8:18



#4 楼

到目前为止,我看不到任何漂亮的打印机,至少可以通过非常简单的格式模仿python解释器的输出,所以这是我的:

class Formatter(object):
    def __init__(self):
        self.types = {}
        self.htchar = '\t'
        self.lfchar = '\n'
        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='\t', lfchar='\n', 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字符串)可以完全表示...)。
使用类版本,您可以为所需的每种对象类型添加格式,也可以为已定义的对象类型更改格式。 >我们可以根据需要更改缩进和换行符。
字典,列表和元组的印刷精美。


评论


这绝对应该是公认的解决方案-缺少对JSON的依赖是巨大的。

–乔什
2014年11月13日15:43

如果可以通过将对象转换为字典并将其键设置为对象类型来处理对象,那将很酷

– Alex Cory
16-09-22在4:37

您基本上可以在内部或外部替换format_object方法来执行此操作。

–.y.petermann
16-09-23在17:45

set_formater-需要两个t,这是一个错字,应该是formatter

– Nikolay Prokopyev
19年6月26日在18:06

#5 楼

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

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


评论


假设字典的内容是json可序列化的,这不一定是正确的。

– SpiXel
19-10-7在11:20

#6 楼

最Python的方法之一就是使用已经构建的pprint模块。 pre class =“ lang-py prettyprint-override”> depth

就是这样!

评论


快速自省甚至更好:来自pprinit import pprint; pprint(mydict)

–mikezter
20/12/21在17:38

#7 楼

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]
    }
}


评论


该解决方案假定默认情况下已安装yapf,而默认情况下未安装。您可以安装它pip install yapf。如果您使用的是conda conda,请安装yapf

– Medhat
20-10-5在22:12



#8 楼

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

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


#9 楼

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
    }
}


它的主要用例是用于调试因此它不会阻塞对象实例或其他任何东西,并且可以处理unicode输出,可以在python 2.7和3中运行。 />

评论


不幸的是,它不适用于Windows,如果您清楚地显示了受支持的系统,那将是很好的选择

–曼德拉
20 Nov 11在17:24



@Mandera如果您可以在github.com/Jaymon/pout/issues上打开一个带有详细信息的问题,因为我想不出它为什么不能在Windows上运行,我们可以在那继续讨论

– Jaymon
20/11/11在23:09

哦,确定的东西!我的错误是假设您没有尝试支持它

–曼德拉
20年11月12日下午6:35

#10 楼

我听了sth的回答,并对其做了一些修改,以适应嵌套字典和列表的需求: >
def pretty(d, indent=0):
    if isinstance(d, dict):
        for key, value in d.iteritems():
            print '\t' * indent + str(key)
            if isinstance(value, dict) or isinstance(value, list):
                pretty(value, indent+1)
            else:
                print '\t' * (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 '\t' * (indent+1) + str(item)
    else:
        pass


#11 楼

您可以使用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的作者

评论


这是最简单的解决方案。非常适合带有大量嵌套键的大型词典。

– Alexei Marinichenko
20年8月24日在14:43



#12 楼

我也必须传递default参数,如下所示:错误:
print(json.dumps(my_dictionary, indent=4, default=str))

由于日期时间是字典中的某些值而导致。

评论


原始答案的出色改进,谢谢您的跟进!

–纳撒尼尔·鲁伊斯(Nathaniel Ruiz)
20 Nov 16 '23:39

#13 楼

我写了这个简单的代码来打印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'):
}


#14 楼

某物,我下沉了;)

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


评论


-1:不处理非dict实例的列表值,即pretty({'key':[1、2、3]},indent = 4)==> AttributeError:'int'对象没有属性'迭代”。我也不喜欢大写字母的键。

–马丁内
13年5月24日在2:36



您的解决方案认为根字典中的列表内不能有字典。它还认为我们不想对列表或元组进行漂亮打印。最后不要大写键,{'a':0,'A':1}的结果将不正确。

– y.petremann
2014年11月22日上午11:07

#15 楼

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)


#16 楼

我只是在回答某事并做出了一个小巧但非常有用的修改后才回到这个问题。此功能可打印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_object['key1']['key2']['value2']内部,因为格式化为字符串的值的长度非常大。 br />

#17 楼

我本人是一位相对较新的python新手,但过去两周来我一直在使用嵌套字典,而这正是我想出的。

您应该尝试使用堆栈。将根字典中的键设为列表列表:

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


从倒序到第一,按顺序查找字典中的每个键,看是否值(也是)字典。如果不是,请打印密钥,然后将其删除。但是,如果键的值是字典,请打印键,然后将该值的键附加到堆栈的末尾,并以相同的方式开始处理该列表,对每个新的键列表进行递归重复。 >
如果每个列表中第二个键的值都是字典,则经过几轮后您将得到类似的结果:缩进量只是\t乘以堆栈长度:

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


缺点是,要检查每个键,您需要将其散列到相关子-dictionary,尽管可以很容易地通过列表理解和简单的for循环来处理它:并删除任何列表中的最后一个键,然后再删除一个空列表(当然这可能会创建另一个空列表,依此类推)。

还有其他方法可以实现s的方法,但希望它能为您提供基本的操作方法。 br />

#18 楼

这是我根据某人的评论编写的函数。它的工作方式与带缩进的json.dumps相同,但我使用的是制表符而不是缩进空间。在Python 3.2+中,您可以直接将缩进指定为'\ t',但在2.7中则不能。缩进

q:

评论


我无法使其与解决方案的嵌套字典配合使用,因为它给了我UnicodeEncodeError,而且项和键都转换为字符串,如果我们使用包含列表和字典的数字或元组怎么办?最后,您的解决方案要考虑到我们要漂亮打印的对象必须是字典。

– y.petremann
2014年10月6日4:26



我不是想为python字典编写通用的打印功能。评分最高的评论已经演示了如何漂亮地打印字典。我的贡献是用``\ t''替代json.dumps来缩进而不是python 2.7中的选项卡。

– Al Conrad
2014年10月8日在18:47

我同意编写json.dumps的替代方案,对我来说,与json.dumps相同的问题也适用。另外,您可以使用简单的正则表达式来更改缩进类型,从而使代码更简单。

– y.petremann
2014年10月8日在21:46

#19 楼

这将打印出任何嵌套的字典,同时跟踪整个“父”字典。

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 '\n'
    elif isinstance(value, dict):
        dicList.append(key)
        prettierPrint(value, dicList)
    if dicList:
         if count == len(dic):
             dicList.pop()
             count = 0

prettierPrint(dicExample, dicList)


这是根据不同格式(如OP中指定的格式)进行打印的良好起点。您真正需要做的就是围绕“打印”块进行操作。请注意,它会查看该值是否为“ OrderedDict()”。根据您是否使用的是Container数据类型集合中的某些内容,应进行此类故障保护,以使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位置来实现。

#20 楼

通过此链接:

def prnDict(aDict, br='\n', html=0,
            keyAlign='l',   sortKey=0,
            keyPrefix='',   keySuffix='',
            valuePrefix='', valueSuffix='',
            leftMargin=0,   indent=1 ):
    '''
return a string representive of aDict in the following format:
    {
     key1: value1,
     key2: value2,
     ...
     }

Spaces will be added to the keys to make them have same width.

sortKey: set to 1 if want keys sorted;
keyAlign: either 'l' or 'r', for left, right align, respectively.
keyPrefix, keySuffix, valuePrefix, valueSuffix: The prefix and
   suffix to wrap the keys or values. Good for formatting them
   for html document(for example, keyPrefix='<b>', keySuffix='</b>'). 
   Note: The keys will be padded with spaces to have them
         equally-wide. The pre- and suffix will be added OUTSIDE
         the entire width.
html: if set to 1, all spaces will be replaced with '&nbsp;', and
      the entire output will be wrapped with '<code>' and '</code>'.
br: determine the carriage return. If html, it is suggested to set
    br to '<br>'. If you want the html source code eazy to read,
    set br to '<br>\n'

version: 04b52
author : Runsun Pan
require: odict() # an ordered dict, if you want the keys sorted.
         Dave Benjamin 
         http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/161403
    '''

    if aDict:

        #------------------------------ sort key
        if sortKey:
            dic = aDict.copy()
            keys = dic.keys()
            keys.sort()
            aDict = odict()
            for k in keys:
                aDict[k] = dic[k]

        #------------------- wrap keys with ' ' (quotes) if str
        tmp = ['{']
        ks = [type(x)==str and "'%s'"%x or x for x in aDict.keys()]

        #------------------- wrap values with ' ' (quotes) if str
        vs = [type(x)==str and "'%s'"%x or x for x in aDict.values()] 

        maxKeyLen = max([len(str(x)) for x in ks])

        for i in range(len(ks)):

            #-------------------------- Adjust key width
            k = {1            : str(ks[i]).ljust(maxKeyLen),
                 keyAlign=='r': str(ks[i]).rjust(maxKeyLen) }[1]

            v = vs[i]        
            tmp.append(' '* indent+ '%s%s%s:%s%s%s,' %(
                        keyPrefix, k, keySuffix,
                        valuePrefix,v,valueSuffix))

        tmp[-1] = tmp[-1][:-1] # remove the ',' in the last item
        tmp.append('}')

        if leftMargin:
          tmp = [ ' '*leftMargin + x for x in tmp ]

        if html:
            return '<code>%s</code>' %br.join(tmp).replace(' ','&nbsp;')
        else:
            return br.join(tmp)     
    else:
        return '{}'

'''
Example:

>>> a={'C': 2, 'B': 1, 'E': 4, (3, 5): 0}

>>> print prnDict(a)
{
 'C'   :2,
 'B'   :1,
 'E'   :4,
 (3, 5):0
}

>>> print prnDict(a, sortKey=1)
{
 'B'   :1,
 'C'   :2,
 'E'   :4,
 (3, 5):0
}

>>> print prnDict(a, keyPrefix="<b>", keySuffix="</b>")
{
 <b>'C'   </b>:2,
 <b>'B'   </b>:1,
 <b>'E'   </b>:4,
 <b>(3, 5)</b>:0
}

>>> print prnDict(a, html=1)
<code>{
&nbsp;'C'&nbsp;&nbsp;&nbsp;:2,
&nbsp;'B'&nbsp;&nbsp;&nbsp;:1,
&nbsp;'E'&nbsp;&nbsp;&nbsp;:4,
&nbsp;(3,&nbsp;5):0
}</code>

>>> b={'car': [6, 6, 12], 'about': [15, 9, 6], 'bookKeeper': [9, 9, 15]}

>>> print prnDict(b, sortKey=1)
{
 'about'     :[15, 9, 6],
 'bookKeeper':[9, 9, 15],
 'car'       :[6, 6, 12]
}

>>> print prnDict(b, keyAlign="r")
{
        'car':[6, 6, 12],
      'about':[15, 9, 6],
 'bookKeeper':[9, 9, 15]
}
'''


#21 楼

使用此功能:

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)


评论


如果值是字符串,则此方法不起作用。它在新行上打印字符串的每个字符,但是按键似乎可以正常工作。

–安东尼
20-2-9在17:52

#22 楼

这是我在处理需要在.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': '',
    },
}