我知道字典和集合是无序的,因此相等的集合或字典可能会打印不同(所有测试均使用 Python 3.6.1):
>>> for obj in {0, 8}, {8, 0}, {0:0, 8:8}, {8:8, 0:0}: print(obj) {0, 8} {8, 0} {0: 0, 8: 8} {8: 8, 0: 0}
我刚刚意识到pprint(“pretty-print”)对字典进行排序,但不对集合进行排序:
pprint
>>> for obj in {0, 8}, {8, 0}, {0:0, 8:8}, {8:8, 0:0}: pprint.pprint(obj) {0, 8} {8, 0} {0: 0, 8: 8} {0: 0, 8: 8}
它的文档还说“在计算显示之前,字典按键排序”。但为什么它不排序集合呢?我觉得不太好。有没有办法让它排序集合?也可以在嵌套结构中排序,因为这是 的主要目的pprint。
pprint 对字典进行了排序,但不对集合排序,这是因为集合本质上是无序的,而字典在 Python 3.7(实际上是从 3.6 开始)之后具有插入顺序,这使得排序字典变得有意义。pprint 默认按键排序字典以便输出更具可读性,但在集合上不强制排序,因为集合没有键值对,且对顺序没有相同的需求。
不过,你可以通过自定义的方式实现集合的排序,并在需要时对集合进行排序打印。可以编写一个小的包装函数,在打印前先对集合排序。
以下代码在遇到集合时对其进行排序打印:
import pprint def pprint_sorted(obj): if isinstance(obj, set): # 对集合排序并转换为列表,这样打印会有序 obj = sorted(obj) elif isinstance(obj, dict): # 对字典的键值对排序(递归处理嵌套的集合或字典) obj = {k: pprint_sorted(v) for k, v in sorted(obj.items())} elif isinstance(obj, (list, tuple)): # 对列表或元组中包含的元素递归排序 obj = type(obj)(pprint_sorted(v) for v in obj) return obj # 测试代码 data = [{0, 8}, {8, 0}, {0:0, 8:8}, {8:8, 0:0}] for item in data: pprint.pprint(pprint_sorted(item))
这样,你会看到集合和字典都已排序后的结果:
[0, 8] [0, 8] {0: 0, 8: 8} {0: 0, 8: 8}
pprint_sorted
这样可以保证即使在复杂嵌套结构中,集合和字典都可以有序输出。