tags:

views:

512

answers:

3

I would like to print a python dictionary to a file using PrettyPrinter (for human readability) but have the dictionary be sorted by key in the output file to further improve readability. So:

mydict = {'a':1, 'b':2, 'c':3}
pprint(mydict)

currently prints to

{'b':2,
 'c':3,
 'a':1}

I would like to PrettyPrint the dictionary but have it printed out sorted by key eg.

{'a':1,
 'b':2,
 'c':3}

What is the best way to do this?

+1  A: 

You could transform this dict a little to ensure that (as dicts aren't kept sorted internally), e.g.

pprint([(key, mydict[key]) for key in sorted(mydict.keys())])
PiotrLegnica
+6  A: 

The Python pprint module actually already sorts dictionaries by key. In versions prior to Python 2.5, the sorting was only triggered on dictionaries whose pretty-printed representation spanned multiple lines, but in 2.5.X and 2.6.X, all dictionaries are sorted.

Generally, though, if you're writing data structures to a file and want them human-readable and writable, you might want to consider using an alternate format like YAML or JSON. Unless your users are themselves programmers, having them maintain configuration or application state dumped via pprint and loaded via eval can be a frustrating and error-prone task.

rcoder
+1 YAML for readability.
toby
btw, `ast.literal_eval("{'a': 0, 'b': 1, 2: 'c'}")` -> `{2: 'c', 'a': 0, 'b': 1}` so there is no need for impious `eval`.
J.F. Sebastian
+3  A: 

Actually pprint seems to sort the keys for you under python2.5

>>> from pprint import pprint
>>> mydict = {'a':1, 'b':2, 'c':3}
>>> pprint(mydict)
{'a': 1, 'b': 2, 'c': 3}
>>> mydict = {'a':1, 'b':2, 'c':3, 'd':4, 'e':5}
>>> pprint(mydict)
{'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
>>> d = dict(zip("kjihgfedcba",range(11)))
>>> pprint(d)
{'a': 10,
 'b': 9,
 'c': 8,
 'd': 7,
 'e': 6,
 'f': 5,
 'g': 4,
 'h': 3,
 'i': 2,
 'j': 1,
 'k': 0}

But not always under python 2.4

>>> from pprint import pprint
>>> mydict = {'a':1, 'b':2, 'c':3, 'd':4, 'e':5}
>>> pprint(mydict)
{'a': 1, 'c': 3, 'b': 2, 'e': 5, 'd': 4}
>>> d = dict(zip("kjihgfedcba",range(11)))
>>> pprint(d)
{'a': 10,
 'b': 9,
 'c': 8,
 'd': 7,
 'e': 6,
 'f': 5,
 'g': 4,
 'h': 3,
 'i': 2,
 'j': 1,
 'k': 0}
>>>

Reading the source code of pprint.py (2.5) it does sort the dictionary using

items = object.items()
items.sort()

for multiline or this for single line

for k, v in sorted(object.items()):

before it attempts to print anything, so if your dictionary sorts properly like that then it should pprint properly. In 2.4 the second sorted() is missing (didn't exist then) so objects printed on a single line won't be sorted.

So the answer appears to be use python2.5, though this doesn't quite explain your output in the question.

Nick Craig-Wood