By Antony


2012-01-25 10:54:29 8 Comments

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.

25 comments

@Guangyang Li 2018-01-08 17:34:17

Python dictionary was unordered before Python 3.6. In CPython implementation of Python 3.6, dictionary keeps the insertion order. From Python 3.7, this will become a language feature.

In changelog of Python 3.6 (https://docs.python.org/3.6/whatsnew/3.6.html#whatsnew36-compactdict):

The order-preserving aspect of this new implementation is considered an implementation detail and should not be relied upon (this may change in the future, but it is desired to have this new dict implementation in the language for a few releases before changing the language spec to mandate order-preserving semantics for all current and future Python implementations; this also helps preserve backwards-compatibility with older versions of the language where random iteration order is still in effect, e.g. Python 3.5).

In document of Python 3.7 (https://docs.python.org/3.7/tutorial/datastructures.html#dictionaries):

Performing list(d) on a dictionary returns a list of all the keys used in the dictionary, in insertion order (if you want it sorted, just use sorted(d) instead).

So unlike previous versions, you can sort a dict after Python 3.6/3.7. If you want to sort a nested dict including the sub-dict inside, you can do:

test_dict = {'a': 1, 'c': 3, 'b': {'b2': 2, 'b1': 1}}

def dict_reorder(item):
    return {k: sort_dict(v) if isinstance(v, dict) else v for k, v in sorted(item.items())}

reordered_dict = dict_reorder(test_dict)

https://gist.github.com/ligyxy/f60f0374defc383aa098d44cfbd318eb

@Jeevan Chaitanya 2018-12-13 05:31:12

I come up with single line dict sorting.

>> a = {2:3, 1:89, 4:5, 3:0}
>> c = {i:a[i] for i in sorted(a.keys())}
>> print(c)
{1: 89, 2: 3, 3: 0, 4: 5}
[Finished in 0.4s]

Hope this will be helpful.

@Dipu 2017-10-30 14:33:37

For python3.6+, 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}

@olibre 2018-04-18 07:07:15

Unfortunately this trick does not always work. For example d = {22:3, -1111:89, 44444444444:5, 3333:0} and d = {"f2":3, "a1":89, "z4":5, "m3":0}. Please note python documentation says It is best to think of a dictionary as an unordered set of key.

@Dipu 2018-07-15 07:19:26

I do not see your point. The question asked to sort by keys. And my code gives the correct answer for both of your examples. For the first case: d = {-1111: 89, 22: 3, 3333: 0, 44444444444: 5} and for the second: d = {'a1': 89, 'f2': 3, 'm3': 0, 'z4': 5}. I think both are legitly sorted by keys.

@tmck-code 2018-09-04 22:20:09

Nice, the best answer IMO. I think it might need the caveat that this will only reliably work in 3.6+?

@U9-Forward 2018-10-17 06:42:10

Or use pandas,

Demo:

>>> d={'B':1,'A':2,'C':3}
>>> df=pd.DataFrame(d,index=[0]).sort_index(axis=1)
   A  B  C
0  2  1  3
>>> df.to_dict('int')[0]
{'A': 2, 'B': 1, 'C': 3}
>>> 

See:

Docs of this

Documentation of whole pandas

@Amit Prafulla 2018-06-16 09:14:56

You can create a new dictionary by sorting the current dictionary by key as per your question.

This is your dictionary

d = {2:3, 1:89, 4:5, 3:0}

Create a new dictionary d1 by sorting this d using lambda function

d1 = dict(sorted(d.items(), key = lambda x:x[0]))

d1 should be {1: 89, 2: 3, 3: 0, 4: 5}, sorted based on keys in d.

@Mahdi Ghelichi 2017-10-11 20:19:03

dictionary = {1:[2],2:[],5:[4,5],4:[5],3:[1]}

temp=sorted(dictionary)
sorted_dict = dict([(k,dictionary[k]) for i,k in enumerate(temp)])

sorted_dict:
         {1: [2], 2: [], 3: [1], 4: [5], 5: [4, 5]}

@lallolu 2017-03-14 14:45:16

I think the easiest thing is to sort the dict by key and save the sorted key:value pair in a new dict.

dict1 = {'renault': 3, 'ford':4, 'volvo': 1, 'toyota': 2} 
dict2 = {}                  # create an empty dict to store the sorted values
for key in sorted(dict1.keys()):
    if not key in dict2:    # Depending on the goal, this line may not be neccessary
        dict2[key] = dict1[key]

To make it clearer:

dict1 = {'renault': 3, 'ford':4, 'volvo': 1, 'toyota': 2} 
dict2 = {}                  # create an empty dict to store the sorted     values
for key in sorted(dict1.keys()):
    if not key in dict2:    # Depending on the goal, this line may not be  neccessary
        value = dict1[key]
        dict2[key] = value

@jax 2017-03-02 11:20:20

Will generate exactly what you want:

 D1 = {2:3, 1:89, 4:5, 3:0}

 sort_dic = {}

 for i in sorted(D1):
     sort_dic.update({i:D1[i]})
 print sort_dic


{1: 89, 2: 3, 3: 0, 4: 5}

But this is not the write way to do this, because, It could show a distinct behavior with different dictionaries , which I have learned recently. Hence perfect way has been suggested by Tim In the response of my Query which I am sharing here.

from collections import OrderedDict
sorted_dict = OrderedDict(sorted(D1.items(), key=lambda t: t[0]))

@Shafiq 2017-01-26 04:17:45

Simplest solution is that you should get a list of dict key is sorted order and then iterate over dict. For example

a1 = {'a':1, 'b':13, 'd':4, 'c':2, 'e':30}
a1_sorted_keys = sorted(a1, key=a1.get, reverse=True)
for r in a1_sorted_keys:
    print r, a1[r]

Following will be the output (desending order)

e 30
b 13
d 4
c 2
a 1

@Sree 2017-01-19 04:29:57

There is an easy way to sort a dictionary.

According to your question,

The solution is :

c={2:3, 1:89, 4:5, 3:0}
y=sorted(c.items())
print y

(Where c,is the name of your dictionary.)

This program gives the following output:

[(1, 89), (2, 3), (3, 0), (4, 5)]

like u wanted.

Another example is:

d={"John":36,"Lucy":24,"Albert":32,"Peter":18,"Bill":41}
x=sorted(d.keys())
print x

Gives the output:['Albert', 'Bill', 'John', 'Lucy', 'Peter']

y=sorted(d.values())
print y

Gives the output:[18, 24, 32, 36, 41]

z=sorted(d.items())
print z

Gives the output:

[('Albert', 32), ('Bill', 41), ('John', 36), ('Lucy', 24), ('Peter', 18)]

Hence by changing it into keys, values and items , you can print like what u wanted.Hope this helps!

@Mohammad Mahjoub 2016-11-25 19:17:08

from operator import itemgetter
# if you would like to play with multiple dictionaries then here you go:
# Three dictionaries that are composed of first name and last name.
user = [
    {'fname': 'Mo', 'lname': 'Mahjoub'},
    {'fname': 'Abdo', 'lname': 'Al-hebashi'},
    {'fname': 'Ali', 'lname': 'Muhammad'}
]
#  This loop will sort by the first and the last names.
# notice that in a dictionary order doesn't matter. So it could put the first name first or the last name first. 
for k in sorted (user, key=itemgetter ('fname', 'lname')):
    print (k)

# This one will sort by the first name only.
for x in sorted (user, key=itemgetter ('fname')):
    print (x)

@user7070507 2016-10-25 15:30:39

l = dict.keys()
l2 = l
l2.append(0)
l3 = []
for repeater in range(0, len(l)):
    smallnum = float("inf")
    for listitem in l2:
        if listitem < smallnum:
            smallnum = listitem
    l2.remove(smallnum)
    l3.append(smallnum)
l3.remove(0)
l = l3

for listitem in l:
    print(listitem)

@FelixSFD 2016-10-25 15:53:22

There are 14 other answers. Can you explain your code a bit and why it might be better than the other solutions?

@Captain Lepton 2016-12-08 16:17:54

Downvoted - Pretty unreadable code with short meaningless variable names l, l2, l3. Seems to be an attempt at an indirect and inefficient algorithm with no knowledge of python standard functions, and in any case does not work when tested on small example in original post.

@Jesuisme 2016-09-26 23:59:55

A timing comparison of the two methods in 2.7 shows them to be virtually identical:

>>> setup_string = "a = sorted(dict({2:3, 1:89, 4:5, 3:0}).items())"
>>> timeit.timeit(stmt="[(k, val) for k, val in a]", setup=setup_string, number=10000)
0.003599141953657181

>>> setup_string = "from collections import OrderedDict\n"
>>> setup_string += "a = OrderedDict({1:89, 2:3, 3:0, 4:5})\n"
>>> setup_string += "b = a.items()"
>>> timeit.timeit(stmt="[(k, val) for k, val in b]", setup=setup_string, number=10000)
0.003581275490432745 

@Derick Fdo 2016-09-15 05:27:11

Guys you are making things complicated ... it's really simple

from pprint import pprint
Dict={'B':1,'A':2,'C':3}
pprint(Dict)

The output is:

{'A':2,'B':1,'C':3}

@Captain Lepton 2016-12-08 16:13:37

Upvoted because I didn't know pprint sorts dictionaries to display them, but the OP has really asked about "going" from unsorted to sorted dict, ie OP seems to want something that remains sorted in memory, perhaps for some algorithm that requires sorted keys

@user4322543 2016-12-08 19:02:13

This method will not allow chained assignment as pprint returns none. >>> adict = {'B':1,'A':2,'C':3} >>> ppdict = pprint(adict) {'A': 2, 'B': 1, 'C': 3} >>> ppdict.type() Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'NoneType' object has no attribute 'type'

@tschesseket 2014-03-12 21:43:42

Found another way:

import json
print json.dumps(d, sort_keys = True)

upd:
1. this also sorts nested objects (thanks @DanielF).
2. python dictionaries are unordered therefore this is sutable for print or assign to str only.

@Daniel F 2015-07-17 21:08:08

But this also sorts the keys of nested objects, which might not be wanted.

@tschesseket 2016-05-24 00:27:18

@DanielF I updated the answer, thanks.

@Andrew 2017-08-18 20:08:10

Note that this only sorts dictionaries, not lists, e.g. dict.keys() will not be sorted because it is a list.

@Lusine 2016-05-17 08:55:57

If you have a dict, for example:

not_ordered_dict = {5 : "5555", 9 : "9999", 1 : "1111"}

ordered_dict = {}

for key in sorted(not_ordered_dict):
    ordered_dict[key] = not_ordered_dict[key]   

@zondo 2016-05-17 11:04:18

Dictionaries cannot be ordered. Your "ordered" dict will be just like the unordered one. Do a test, and see for yourself.

@NPE 2012-01-25 10:56:30

Standard Python dictionaries are unordered. 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

@Antony 2012-01-25 11:10:05

Thanks, I am using python 2.6.5 and the OrderedDict is for 2.7 and above so its not working..

@Antony 2012-01-25 11:20:26

I used this and it works, I guess its more code and redundancy but gets the job done, # unordered dict d = {2:3, 1:89, 4:5, 3:0} orderedDict = {} for key in sorted(d.iterkeys()): orderedDict[key]=d[key]

@Cédric Julien 2012-01-25 11:20:32

@achrysochoou : then you should use the OrderedDict recipe linked in the python documentation, it works very well for old python

@Ricardo Cárdenes 2012-01-25 11:25:47

@achrysochoou: if that worked, it must have been by sheer luck. As you've been told, regular dictionaries have no concept of sorting, no matter if you assign the keys sorted or in random way.

@Antony 2012-01-25 11:32:03

Thank you all for your help, I will read the suggested documentation and try to follow the correct methodology. Cheers!

@Bob 2014-09-11 16:43:25

@achrysochoou don't write "orderedDict = {}" (as stated in your comment) - this way you are creating simple dict, you should write "od = OrderedDict()" instead

@sdenham 2015-04-01 15:53:32

@Lucretiel : For all practical purposes, you are correct. Arguably, this answer provides some sort of solution to the question as asked, if that is taken very literally, but the question, if taken literally, seems to be predicated on a misunderstanding of the semantics of dictionaries.

@thestephenstanton 2016-09-18 22:07:03

Why not just use sorted(d.items()) and be done with it? Why must you use the OrderedDict()?

@TMWP 2017-03-24 21:47:47

This code helped me today. Your question is from 2016 but I thought I would answer it anyway: ` sorted()` regular dictionaries cannot be stored (at least not in order). You have to sort them again next time you want to output them. Using an ordered dictionary to store the results, the results are now in the dictionary in the sorted order. I built a dictionary where times were the keys, sorted in reverse, and now whenever I output the ordered dictionary, the content is always from newest to oldest. This did not work until I stored it in an ordered dictionary.

@Hardik Gajjar 2018-01-02 10:04:29

It is not working with Alphanumarec key like key1 key2 key3 key4` key5 key6 key7 key8 key9 key10 key11

@holdenweb 2018-03-02 21:23:04

Note that it's likely the upcoming Python 3.7 release will formalise what was originally an implementation change in 3.6: dicts will iterate over their keys or items in insertion order, but 3.6 makes no guarantees. 3.7 will.

@aksh1618 2018-07-15 14:52:49

For python 3.7+: sorted_dict = dict(sorted(unsorted_dict.items()))

@Aneuway 2019-01-25 18:09:21

python 3.7+ shouldn't need orderedDict since it now orders by default :-)

@user3769249 2015-11-12 21:28:37

Simply:

d = {2:3, 1:89, 4:5, 3:0}
sd = sorted(d.items())

for k,v in sd:
    print k, v

Output:

1 89
2 3
3 0
4 5

@nischi 2016-11-24 09:53:29

sd is a list of tuples, not a dictionary. (still useful though.)

@Dennis 2013-03-02 21:04:10

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)])

@benscabbia 2016-08-28 20:03:32

awesome! Guys if you want to reverse the order (ascending TO descending) then you simply add reverse=True e.g. OrderedDict(sorted(d.items(), reverse=True, key=lambda t: t[0]))

@Euler_Salter 2018-07-24 10:00:37

In PyCharm, no matter what dictionary I use, I always get this warning: Unexpected type(s): (List[str]) Possible types: (Mapping) (Iterable[Tuple[Any, Any]])

@James 2012-12-21 13:01:36

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/

@radtek 2015-01-29 22:09:48

You can also use OrderedDict in python 2.4+ as in NPE's answer

@GrantJ 2014-03-28 16:27:02

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])

@mgk 2014-04-18 17:14:32

+1 for addressing the use case of maintaining sorted order and linking pacakges that do so

@Ramashish Baranwal 2014-03-28 04:18:06

Python dicts are un-ordered. Usually, this is not a problem since the most common use case is to do a lookup.

The simplest way to do what you want would be to create a collections.OrderedDict inserting the elements in sorted order.

ordered_dict = collections.OrderedDict([(k, d[k]) for k in sorted(d.keys())])

If you need to iterated, as others above have suggested, the simplest way would be to iterate over sorted keys. Examples-

Print values sorted by keys:

# create the dict
d = {k1:v1, k2:v2,...}
# iterate by keys in sorted order
for k in sorted(d.keys()):
    value = d[k]
    # do something with k, value like print
    print k, value

Get list of values sorted by keys:

values = [d[k] for k in sorted(d.keys())]

@Jean-François Fabre 2018-04-27 19:38:18

for k,value in sorted(d.items()): is better: avoids accessing the dict by key again in the loop

@Atul Arvind 2014-02-03 11:11:48

Here I found some simplest solution to sort the python dict by key using pprint. eg.

>>> x = {'a': 10, 'cd': 20, 'b': 30, 'az': 99} 
>>> print x
{'a': 10, 'b': 30, 'az': 99, 'cd': 20}

but while using pprint it will return sorted dict

>>> import pprint 
>>> pprint.pprint(x)
{'a': 10, 'az': 99, 'b': 30, 'cd': 20}

@Evgeny Tryastsin 2013-12-17 02:22:36

In Python 3.

>>> D1 = {2:3, 1:89, 4:5, 3:0}
>>> for key in sorted(D1):
    print (key, D1[key])

gives

1 89
2 3
3 0
4 5

@Brian 2012-01-25 12:16:27

As others have mentioned, dictionaries are inherently unordered. However, if the issue is merely displaying dictionaries in an ordered fashion, you can override the __str__ method in a dictionary subclass, and use this dictionary class rather than the builtin dict. Eg.

class SortedDisplayDict(dict):
   def __str__(self):
       return "{" + ", ".join("%r: %r" % (key, self[key]) for key in sorted(self)) + "}"


>>> d = SortedDisplayDict({2:3, 1:89, 4:5, 3:0})
>>> d
{1: 89, 2: 3, 3: 0, 4: 5}

Note, this changes nothing about how the keys are stored, the order they will come back when you iterate over them etc, just how they're displayed with print or at the python console.

Related Questions

Sponsored Content

16 Answered Questions

[SOLVED] Check if a given key already exists in a dictionary

  • 2009-10-21 19:05:09
  • Mohan Gulati
  • 2847922 View
  • 2683 Score
  • 16 Answer
  • Tags:   python dictionary

10 Answered Questions

[SOLVED] Iterating over dictionaries using 'for' loops

26 Answered Questions

[SOLVED] How can I safely create a nested directory?

34 Answered Questions

[SOLVED] How do I sort a dictionary by value?

38 Answered Questions

[SOLVED] What does the "yield" keyword do?

15 Answered Questions

[SOLVED] Add new keys to a dictionary?

39 Answered Questions

[SOLVED] How to merge two dictionaries in a single expression?

19 Answered Questions

49 Answered Questions

[SOLVED] Sort a Map<Key, Value> by values

36 Answered Questions

[SOLVED] How to pair socks from a pile efficiently?

Sponsored Content