小能豆

pprint 对字典进行排序但不对集合进行排序?

py

我知道字典和集合是无序的,因此相等的集合或字典可能会打印不同(所有测试均使用 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”)对字典进行排序,但不对集合进行排序:

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


阅读 18

收藏
2024-11-12

共1个答案

小能豆

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}

说明

  1. pprint_sorted 函数会检查输入对象的类型,如果是集合则排序并转换为列表输出。
  2. 如果对象是字典,则递归排序字典的键值对。
  3. 对于嵌套结构,如列表或元组中的集合或字典,这种递归机制会处理每个内部元素的排序。

这样可以保证即使在复杂嵌套结构中,集合和字典都可以有序输出。

2024-11-12