Python 美观地输出字典,你可能试过在程序中插入许多print
语句来跟踪执行流程,以此来调试bug或生成日志信息来输出某些配置设置。
我在Python中以字符串形式打印一些数据结构时,输出结果会难以阅读,因此我常常感到很沮丧。例如下面有个简单的字典,在解释器会话中输出时不仅键是乱序排列,而且字符串中也没有缩进:
>>> mapping = {'a': 23, 'b': 42, 'c': 0xc0ffee}
>>> str(mapping)
{'b': 42, 'c': 12648430, 'a': 23}
幸运的是,有一些方便的方法能直观地将字典转换成可读的结果。一种是使用Python的内置json
模块,即使用json.dumps()
以更好的格式输出Python字典:
>>> import json
>>> json.dumps(mapping, indent=4, sort_keys=True)
{
"a": 23,
"b": 42,
"c": 12648430
}
这些设置会生成带有缩进的字符串表示形式,同时对字典键的顺序进行规范化处理以提高可读性。
虽然结果看起来不错且可读,但还不是完美的解决方案。json
模块只能序列化含有特定类型的字典。对于Python 3.7能够序列化的内置类型有:
dict
-
list
、tuple
-
str
-
int
、float
(和一些Enum
) -
bool
-
None
这意味着如果字典含有不支持的数据类型,如函数,那么在打印时会遇到问题:
>>> json.dumps({all: 'yup'})
TypeError: "keys must be a string"
尝试使用json.dumps()
来序列化其他内置数据类型也会遇到这种问题:
>>> mapping['d'] = {1, 2, 3}
>>> json.dumps(mapping)
TypeError: "set([1, 2, 3]) is not JSON serializable"
此外,在序列化Unicode文本时可能会遇到问题——将从json.dumps()
得到的字符串复制粘贴到Python解释器会话中有时并不能重建原字典对象。
总之这种方法有许多缺点,下面来看另一种更通用的方法。在Python中美观输出对象的经典办法是使用内置的pprint
模块,来看一个例子:
>>> import pprint
>>> pprint.pprint(mapping)
{'a': 23, 'b': 42, 'c': 12648430, 'd': set([1, 2, 3])}
可以看到,pprint
能够打印像集合这样的数据类型,同时还能以固定顺序打印字典键。与字典的标准字符串形式相比,其结果更适合阅读。
不过与json.dumps()
相比,pprint
并不能很好地表示嵌套结构。有时这是优点,有时则是缺点。我偶尔会使用json.dumps()
打印字典,其可读性和格式化都更好,但前提是字典中只含有JSON能够序列化的数据类型。
关键要点
-
Python中字典对象的默认字符串转换结果可能不适合阅读。
-
pprint
和json
模块是Python标准库内置模块,能精确、清晰地打印字典。 -
注意只能对JSON能够序列化的键和值类型使用
json.dumps()
,否则会触发TypeError
。