Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sorting dictionary python 3

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!

like image 680
Jjang Avatar asked Jun 18 '12 19:06

Jjang


People also ask

Is it possible to sort a dictionary in python?

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.

Can we sort a dictionary with keys in Python?

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.


1 Answers

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.

  • You can generate sorted dict using dict comprehensions.
  • Using OrderedDict might still be preferable for the compatibility sake.
  • Do not use 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)}") 
like image 102
krassowski Avatar answered Sep 21 '22 01:09

krassowski