I'm working on python 3.2.2. Breaking my head more than 3 hours to sort a dictionary by it's keys. I managed to make it a sorted list with 2 argument members, but can not make it a sorted dictionary in the end.
This is what I've figured:
myDic={10: 'b', 3:'a', 5:'c'} sorted_list=sorted(myDic.items(), key=lambda x: x[0])
But no matter what I can not make a dictionary out of this sorted list. How do I do that? Thanks!
Introduction. We can sort lists, tuples, strings, and other iterable objects in python since they are all ordered objects. Well, as of python 3.7, dictionaries remember the order of items inserted as well. Thus we are also able to sort dictionaries using python's built-in sorted() function.
Python offers the built-in keys functions keys() and values() functions to sort the dictionary. It takes any iterable as an argument and returns the sorted list of keys. We can use the keys to sort the dictionary in the ascending order.
A modern and fast solution, for Python 3.7. May also work in some interpreters of Python 3.6.
TLDR
To sort a dictionary by keys use:
sorted_dict = {k: disordered[k] for k in sorted(disordered)}
Almost three times faster than the accepted answer; probably more when you include imports.
Comment on the accepted answer
The example in the accepted answer instead of iterating over the keys only - with key
parameter of sorted()
or the default behaviour of dict iteration - iterates over tuples (key, value)
, which suprisingly turns out to be much slower than comparing the keys only and accessing dictionary elements in a list comprehension.
How to sort by key in Python 3.7
The big change in Python 3.7 is that the dictionaries are now ordered by default.
OrderedDict
might still be preferable for the compatibility sake.sorted(d.items())
without key
.See:
disordered = {10: 'b', 3: 'a', 5: 'c'} # sort keys, then get values from original - fast sorted_dict = {k: disordered[k] for k in sorted(disordered)} # key = itemgetter - slower from operator import itemgetter key = itemgetter(0) sorted_dict = {k: v for k, v in sorted(disordered.items(), key=key)} # key = lambda - the slowest key = lambda item: item[0] sorted_dict = {k: v for k in sorted(disordered.items(), key=key)}
Timing results:
Best for {k: d[k] for k in sorted(d)}: 7.507327548999456 Best for {k: v for k, v in sorted(d.items(), key=key_getter)}: 12.031082626002899 Best for {k: v for k, v in sorted(d.items(), key=key_lambda)}: 14.22885995300021 Best for dict(sorted(d.items(), key=key_getter)): 11.209122000000207 Best for dict(sorted(d.items(), key=key_lambda)): 13.289728325995384 Best for dict(sorted(d.items())): 14.231471302999125 Best for OrderedDict(sorted(d.items(), key=key_getter)): 16.609151654003654 Best for OrderedDict(sorted(d.items(), key=key_lambda)): 18.52622927199991 Best for OrderedDict(sorted(d.items())): 19.436101284998585
Testing code:
from timeit import repeat setup_code = """ from operator import itemgetter from collections import OrderedDict import random random.seed(0) d = {i: chr(i) for i in [random.randint(0, 120) for repeat in range(120)]} key_getter = itemgetter(0) key_lambda = lambda item: item[0] """ cases = [ # fast '{k: d[k] for k in sorted(d)}', '{k: v for k, v in sorted(d.items(), key=key_getter)}', '{k: v for k, v in sorted(d.items(), key=key_lambda)}', # slower 'dict(sorted(d.items(), key=key_getter))', 'dict(sorted(d.items(), key=key_lambda))', 'dict(sorted(d.items()))', # the slowest 'OrderedDict(sorted(d.items(), key=key_getter))', 'OrderedDict(sorted(d.items(), key=key_lambda))', 'OrderedDict(sorted(d.items()))', ] for code in cases: times = repeat(code, setup=setup_code, repeat=3) print(f"Best for {code}: {min(times)}")
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