How can I sort a dictionary by key?
What would be a nice way to go from {2:3, 1:89, 4:5, 3:0}
to {1:89, 2:3, 3:0, 4:5}
?
I checked some posts but they all use the "sorted" operator that returns tuples.
Solution 1:
Standard Python dictionaries are unordered (until Python 3.7). Even if you sorted the (key,value) pairs, you wouldn't be able to store them in a dict
in a way that would preserve the ordering.
The easiest way is to use OrderedDict
, which remembers the order in which the elements have been inserted:
In [1]: import collections
In [2]: d = {2:3, 1:89, 4:5, 3:0}
In [3]: od = collections.OrderedDict(sorted(d.items()))
In [4]: od
Out[4]: OrderedDict([(1, 89), (2, 3), (3, 0), (4, 5)])
Never mind the way od
is printed out; it'll work as expected:
In [11]: od[1]
Out[11]: 89
In [12]: od[3]
Out[12]: 0
In [13]: for k, v in od.iteritems(): print k, v
....:
1 89
2 3
3 0
4 5
Python 3
For Python 3 users, one needs to use the .items()
instead of .iteritems()
:
In [13]: for k, v in od.items(): print(k, v)
....:
1 89
2 3
3 0
4 5
Solution 2:
Dictionaries themselves do not have ordered items as such, should you want to print them etc to some order, here are some examples:
In Python 2.4 and above:
mydict = {'carl':40,
'alan':2,
'bob':1,
'danny':3}
for key in sorted(mydict):
print "%s: %s" % (key, mydict[key])
gives:
alan: 2
bob: 1
carl: 40
danny: 3
(Python below 2.4:)
keylist = mydict.keys()
keylist.sort()
for key in keylist:
print "%s: %s" % (key, mydict[key])
Source: http://www.saltycrane.com/blog/2007/09/how-to-sort-python-dictionary-by-keys/
Solution 3:
For CPython/PyPy 3.6, and any Python 3.7 or higher, this is easily done with:
>>> d = {2:3, 1:89, 4:5, 3:0}
>>> dict(sorted(d.items()))
{1: 89, 2: 3, 3: 0, 4: 5}
Solution 4:
From Python's collections
library documentation:
>>> from collections import OrderedDict
>>> # regular unsorted dictionary
>>> d = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2}
>>> # dictionary sorted by key -- OrderedDict(sorted(d.items()) also works
>>> OrderedDict(sorted(d.items(), key=lambda t: t[0]))
OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])
>>> # dictionary sorted by value
>>> OrderedDict(sorted(d.items(), key=lambda t: t[1]))
OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])
>>> # dictionary sorted by length of the key string
>>> OrderedDict(sorted(d.items(), key=lambda t: len(t[0])))
OrderedDict([('pear', 1), ('apple', 4), ('orange', 2), ('banana', 3)])
Solution 5:
There are a number of Python modules that provide dictionary implementations which automatically maintain the keys in sorted order. Consider the sortedcontainers module which is pure-Python and fast-as-C implementations. There is also a performance comparison with other popular options benchmarked against one another.
Using an ordered dict is an inadequate solution if you need to constantly add and remove key/value pairs while also iterating.
>>> from sortedcontainers import SortedDict
>>> d = {2:3, 1:89, 4:5, 3:0}
>>> s = SortedDict(d)
>>> s.items()
[(1, 89), (2, 3), (3, 0), (4, 5)]
The SortedDict type also supports indexed location lookups and deletion which isn't possible with the built-in dict type.
>>> s.iloc[-1]
4
>>> del s.iloc[2]
>>> s.keys()
SortedSet([1, 2, 4])