I know that dicts and sets aren't ordered, so equal sets or dicts may print differently (all tests with 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}
And I just realized that pprint
(“pretty-print”) sorts dicts but not sets:
>>> 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}
It's documentation also says "Dictionaries are sorted by key before the display is computed". But why doesn't it also sort sets? Doesn't seem pretty to me. And is there a way to make it sort sets? Also inside nested structures, as that's a main purpose of pprint
.
Using pprintThe Python pprint module actually already sorts dictionaries by key. The pprint module provides a capability to “pretty-print” arbitrary Python data structures in a form which can be used as input to the interpreter.
To use pprint, begin by importing the library at the top of your Python file. From here you can either use the . pprint() method or instantiate your own pprint object with PrettyPrinter() .
This was raised in issue 27495 and it is a bug, rather than just a design choice, but apparently has not yet been resolved.
Here is another example from the issue that illustrates perhaps more obviously the behavior you identify in Python 3:
>>> import string, pprint >>> pprint.pprint(set(string.digits)) {'7', '1', '9', '8', '3', '0', '2', '5', '6', '4'}
The same applies for frozenset()
too, but note that multi-line pprint
outputs are sorted in Python 3, for example:
>>> pprint.pprint(set(string.digits), width=1) {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}
However, in Python 2, the output from the same original code is sorted:
>>> pprint.pprint(set(string.digits)) set(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'])
I think it is the inconsistency between Python 3 and Python 2, and between the single-line multi-line behavior, that makes this a bug.
For dict
s, a similar example, illustrates as you note, that the output is sorted in either Python 3 or 2, as it should be:
>>> 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}
However, for Python 3.6, it could be considered surprising that pprint
sorts dict
s since they are ordered now. However, since this is just an implementation detail (for now) I guess there is no obligation for pprint
to maintain the insertion order (yet), and doing so would break pprint
's own consistency across Python versions of always sorting dict
s.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With