12

我知道字典和集合没有顺序,所以相等的集合或字典可能会以不同的方式打印(所有测试都使用 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”) 对 dicts 进行排序,而不是对集合进行排序:

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

4

1 回答 1

5

这是在issue 27495中提出的,它是一个错误,而不仅仅是一个设计选择,但显然尚未解决。

这是问题中的另一个示例,它可能更清楚地说明了您在 Python 3 中识别的行为:

>>> import string, pprint
>>> pprint.pprint(set(string.digits))
{'7', '1', '9', '8', '3', '0', '2', '5', '6', '4'}

这同样适用frozenset(),但请注意,多行pprint输出在 Python 3排序,例如:

>>> pprint.pprint(set(string.digits), width=1)
{'0',
 '1',
 '2',
 '3',
 '4',
 '5',
 '6',
 '7',
 '8',
 '9'}

但是,在 Python 2 中,对相同原始代码的输出进行了排序:

>>> pprint.pprint(set(string.digits))
set(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'])

我认为是 Python 3 和 Python 2 之间以及单行多行行为之间的不一致导致了这个错误。

对于dicts,一个类似的示例,如您所见,说明了输出在 Python 3 或 2 中排序,因为它应该是:

>>> pprint.pprint({i:None for i in set(string.digits)})
{'0': None,
 '1': None,
 '2': None,
 '3': None,
 '4': None,
 '5': None,
 '6': None,
 '7': None,
 '8': None,
 '9': None}

pprint但是,对于 Python 3.6, sort s可能被认为是令人惊讶的,dict因为它们order now。但是,由于这只是一个实现细节(目前),我想没有义务pprint维护插入顺序(还),这样做会破坏pprintPython 版本中始终排序的自身的一致性dict

于 2017-07-11T08:07:48.957 回答