Home How do I sort a dictionary by value?

# How do I sort a dictionary by value?

Gern Blanston
1#
Gern Blanston Published in 2009-03-05 00:49:05Z
 I have a dictionary of values read from two fields in a database: a string field and a numeric field. The string field is unique, so that is the key of the dictionary. I can sort on the keys, but how can I sort based on the values? Note: I have read Stack Overflow question How do I sort a list of dictionaries by values of the dictionary in Python? and probably could change my code to have a list of dictionaries, but since I do not really need a list of dictionaries I wanted to know if there is a simpler solution.
jwpfox
2#
 It is not possible to sort a dict, only to get a representation of a dict that is sorted. Dicts are inherently orderless, but other types, such as lists and tuples, are not. So you need an ordered data type to represent sorted values, which will be a list—probably a list of tuples. For instance, import operator x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0} sorted_x = sorted(x.items(), key=operator.itemgetter(1))  sorted_x will be a list of tuples sorted by the second element in each tuple. dict(sorted_x) == x. And for those wishing to sort on keys instead of values: import operator x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0} sorted_x = sorted(x.items(), key=operator.itemgetter(0)) 
Peter Mortensen
3#
Peter Mortensen Reply to 2017-11-28 13:43:47Z
 Technically, dictionaries aren't sequences, and therefore can't be sorted. You can do something like sorted(a_dictionary.values())  assuming performance isn't a huge deal.
Roberto Bonvallet
4#
Roberto Bonvallet Reply to 2014-09-16 17:26:10Z
 Dicts can't be sorted, but you can build a sorted list from them. A sorted list of dict values: sorted(d.values())  A list of (key, value) pairs, sorted by value: from operator import itemgetter sorted(d.items(), key=itemgetter(1)) 
Holger Bille
5#
Holger Bille Reply to 2017-11-09 14:36:18Z
 Pretty much the same as Hank Gay's answer;  sorted([(value,key) for (key,value) in mydict.items()])  Or optimized a bit as suggested by John Fouhy;  sorted((value,key) for (key,value) in mydict.items()) 
S.Lott
6#
 You can create an "inverted index", also from collections import defaultdict inverse= defaultdict( list ) for k, v in originalDict.items(): inverse[v].append( k )  Now your inverse has the values; each value has a list of applicable keys. for k in sorted(inverse): print k, inverse[k] 
Matt Joiner
7#
Matt Joiner Reply to 2010-07-05 08:06:08Z
 You could use: sorted(d.items(), key=lambda x: x[1]) This will sort the dictionary by the values of each entry within the dictionary from smallest to largest.
Peter Mortensen
8#
Peter Mortensen Reply to 2014-04-03 16:59:39Z
 In recent Python 2.7, we have the new OrderedDict type, which remembers the order in which the items were added. >>> d = {"third": 3, "first": 1, "fourth": 4, "second": 2} >>> for k, v in d.items(): ... print "%s: %s" % (k, v) ... second: 2 fourth: 4 third: 3 first: 1 >>> d {'second': 2, 'fourth': 4, 'third': 3, 'first': 1}  To make a new ordered dictionary from the original, sorting by the values: >>> from collections import OrderedDict >>> d_sorted_by_value = OrderedDict(sorted(d.items(), key=lambda x: x[1]))  The OrderedDict behaves like a normal dict: >>> for k, v in d_sorted_by_value.items(): ... print "%s: %s" % (k, v) ... first: 1 second: 2 third: 3 fourth: 4 >>> d_sorted_by_value OrderedDict([('first': 1), ('second': 2), ('third': 3), ('fourth': 4)]) 
Community
9#

## As simple as: sorted(dict1, key=dict1.get)

Well, it is actually possible to do a "sort by dictionary values". Recently I had to do that in a Code Golf (Stack Overflow question Code golf: Word frequency chart). Abridged, the problem was of the kind: given a text, count how often each word is encountered and display a list of the top words, sorted by decreasing frequency.

If you construct a dictionary with the words as keys and the number of occurrences of each word as value, simplified here as:

from collections import defaultdict
d = defaultdict(int)
for w in text.split():
d[w] += 1


then you can get a list of the words, ordered by frequency of use with sorted(d, key=d.get) - the sort iterates over the dictionary keys, using the number of word occurrences as a sort key .

for w in sorted(d, key=d.get, reverse=True):
print w, d[w]


I am writing this detailed explanation to illustrate what people often mean by "I can easily sort a dictionary by key, but how do I sort by value" - and I think the OP was trying to address such an issue. And the solution is to do sort of list of the keys, based on the values, as shown above.

Argun
10#
 from django.utils.datastructures import SortedDict def sortedDictByKey(self,data): """Sorted dictionary order by key""" sortedDict = SortedDict() if data: if isinstance(data, dict): sortedKey = sorted(data.keys()) for k in sortedKey: sortedDict[k] = data[k] return sortedDict 
Peter Mortensen
11#
Peter Mortensen Reply to 2017-11-28 13:44:24Z
 I had the same problem, and I solved it like this: WantedOutput = sorted(MyDict, key=lambda x : MyDict[x])  (People who answer "It is not possible to sort a dict" did not read the question! In fact, "I can sort on the keys, but how can I sort based on the values?" clearly means that he wants a list of the keys sorted according to the value of their values.) Please notice that the order is not well defined (keys with the same value will be in an arbitrary order in the output list).
icedwater
12#
 This is the code: import operator origin_list = [ {"name": "foo", "rank": 0, "rofl": 20000}, {"name": "Silly", "rank": 15, "rofl": 1000}, {"name": "Baa", "rank": 300, "rofl": 20}, {"name": "Zoo", "rank": 10, "rofl": 200}, {"name": "Penguin", "rank": -1, "rofl": 10000} ] print ">> Original >>" for foo in origin_list: print foo print "\n>> Rofl sort >>" for foo in sorted(origin_list, key=operator.itemgetter("rofl")): print foo print "\n>> Rank sort >>" for foo in sorted(origin_list, key=operator.itemgetter("rank")): print foo  Here are the results: Original {'name': 'foo', 'rank': 0, 'rofl': 20000} {'name': 'Silly', 'rank': 15, 'rofl': 1000} {'name': 'Baa', 'rank': 300, 'rofl': 20} {'name': 'Zoo', 'rank': 10, 'rofl': 200} {'name': 'Penguin', 'rank': -1, 'rofl': 10000}  Rofl {'name': 'Baa', 'rank': 300, 'rofl': 20} {'name': 'Zoo', 'rank': 10, 'rofl': 200} {'name': 'Silly', 'rank': 15, 'rofl': 1000} {'name': 'Penguin', 'rank': -1, 'rofl': 10000} {'name': 'foo', 'rank': 0, 'rofl': 20000}  Rank {'name': 'Penguin', 'rank': -1, 'rofl': 10000} {'name': 'foo', 'rank': 0, 'rofl': 20000} {'name': 'Zoo', 'rank': 10, 'rofl': 200} {'name': 'Silly', 'rank': 15, 'rofl': 1000} {'name': 'Baa', 'rank': 300, 'rofl': 20} 
Vallentin
13#
 It can often be very handy to use namedtuple. For example, you have a dictionary of 'name' as keys and 'score' as values and you want to sort on 'score': import collections Player = collections.namedtuple('Player', 'score name') d = {'John':5, 'Alex':10, 'Richard': 7}  sorting with lowest score first: worst = sorted(Player(v,k) for (k,v) in d.items())  sorting with highest score first: best = sorted([Player(v,k) for (k,v) in d.items()], reverse=True)  Now you can get the name and score of, let's say the second-best player (index=1) very Pythonically like this: player = best[1] player.name 'Richard' player.score 7 
ponty
14#
 Use ValueSortedDict from dicts: from dicts.sorteddict import ValueSortedDict d = {1: 2, 3: 4, 4:3, 2:1, 0:0} sorted_dict = ValueSortedDict(d) print sorted_dict.items() [(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)] 
juhoh
15#
 Iterate through a dict and sort it by its values in descending order: $python --version Python 3.2.2$ cat sort_dict_by_val_desc.py dictionary = dict(siis = 1, sana = 2, joka = 3, tuli = 4, aina = 5) for word in sorted(dictionary, key=dictionary.get, reverse=True): print(word, dictionary[word]) \$ python sort_dict_by_val_desc.py aina 5 tuli 4 joka 3 sana 2 siis 1 
Nathaniel Ford
16#
Nathaniel Ford Reply to 2012-11-06 19:27:31Z
 This works in 3.1.x: import operator slovar_sorted=sorted(slovar.items(), key=operator.itemgetter(1), reverse=True) print(slovar_sorted) 
Petr Viktorin
17#
Petr Viktorin Reply to 2012-01-24 19:50:43Z
 If your values are integers, and you use Python 2.7 or newer, you can use collections.Counter instead of dict. The most_common method will give you all items, sorted by the value.
Ivan Sas
18#
Ivan Sas Reply to 2012-06-27 15:49:32Z
 If values are numeric you may also use Counter from collections from collections import Counter x={'hello':1,'python':5, 'world':3} c=Counter(x) print c.most_common() >> [('python', 5), ('world', 3), ('hello', 1)] 
Peter Mortensen
19#
Peter Mortensen Reply to 2014-04-03 17:03:51Z
 Using Python 3.2: x = {"b":4, "a":3, "c":1} for i in sorted(x.values()): print(list(x.keys())[list(x.values()).index(i)]) 
Peter Mortensen
20#
Peter Mortensen Reply to 2014-04-03 17:04:58Z
 You can use the collections.Counter. Note, this will work for both numeric and non-numeric values. >>> x = {1: 2, 3: 4, 4:3, 2:1, 0:0} >>> from collections import Counter >>> #To sort in reverse order >>> Counter(x).most_common() [(3, 4), (4, 3), (1, 2), (2, 1), (0, 0)] >>> #To sort in ascending order >>> Counter(x).most_common()[::-1] [(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)] >>> #To get a dictionary sorted by values >>> from collections import OrderedDict >>> OrderedDict(Counter(x).most_common()[::-1]) OrderedDict([(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)]) 
Abhijit
21#
 For the sake of completeness, I am posting a solution using heapq. Note, this method will work for both numeric and non-numeric values >>> x = {1: 2, 3: 4, 4:3, 2:1, 0:0} >>> x_items = x.items() >>> heapq.heapify(x_items) >>> #To sort in reverse order >>> heapq.nlargest(len(x_items),x_items, operator.itemgetter(1)) [(3, 4), (4, 3), (1, 2), (2, 1), (0, 0)] >>> #To sort in ascending order >>> heapq.nsmallest(len(x_items),x_items, operator.itemgetter(1)) [(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)] 
Peter Mortensen
22#
Peter Mortensen Reply to 2014-04-03 17:07:59Z
 I came up with this one, import operator x = {1: 2, 3: 4, 4:3, 2:1, 0:0} sorted_x = {k[0]:k[1] for k in sorted(x.items(), key=operator.itemgetter(1))}  For Python 3.x: x.items() replacing iteritems(). >>> sorted_x {0: 0, 1: 2, 2: 1, 3: 4, 4: 3}  Or try with collections.OrderedDict! x = {1: 2, 3: 4, 4:3, 2:1, 0:0} from collections import OrderedDict od1 = OrderedDict(sorted(x.items(), key=lambda t: t[1])) 
sweetdream
23#
 In Python 2.7, simply do: from collections import OrderedDict # regular unsorted dictionary d = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2} # dictionary sorted by key 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)])  copy-paste from : http://docs.python.org/dev/library/collections.html#ordereddict-examples-and-recipes Enjoy ;-)
Zags
24#
 This returns the list of key-value pairs in the dictionary, sorted by value from highest to lowest: sorted(d.items(), key=lambda x: x[1], reverse=True)  For the dictionary sorted by key, use the following: sorted(d.items(), reverse=True)  The return is a list of tuples because dictionaries themselves can't be sorted. This can be both printed or sent into further computation.
lessthanl0l
25#
 months = {"January": 31, "February": 28, "March": 31, "April": 30, "May": 31, "June": 30, "July": 31, "August": 31, "September": 30, "October": 31, "November": 30, "December": 31} def mykey(t): """ Customize your sorting logic using this function. The parameter to this function is a tuple. Comment/uncomment the return statements to test different logics. """ return t[1] # sort by number of days in the month #return t[1], t[0] # sort by number of days, then by month name #return len(t[0]) # sort by length of month name #return t[0][-1] # sort by last character of month name # Since a dictionary can't be sorted by value, what you can do is to convert # it into a list of tuples with tuple length 2. # You can then do custom sorts by passing your own function to sorted(). months_as_list = sorted(months.items(), key=mykey, reverse=False) for month in months_as_list: print month 
liuzhijun
26#
 >>> import collections >>> x = {1: 2, 3: 4, 4:3, 2:1, 0:0} >>> sorted_x = collections.OrderedDict(sorted(x.items(), key=lambda t:t[1])) >>> OrderedDict([(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)])  OrderedDict is subclass of dict
Peter Mortensen
27#
Peter Mortensen Reply to 2014-04-03 17:10:13Z
 Because of requirements to retain backward compatability with older versions of Python I think the OrderedDict solution is very unwise. You want something that works with Python 2.7 and older versions. But the collections solution mentioned in another answer is absolutely superb, because you retrain a connection between the key and value which in the case of dictionaries is extremely important. I don't agree with the number one choice presented in another answer, because it throws away the keys. I used the solution mentioned above (code shown below) and retained access to both keys and values and in my case the ordering was on the values, but the importance was the ordering of the keys after ordering the values. from collections import Counter x = {'hello':1, 'python':5, 'world':3} c=Counter(x) print c.most_common() >> [('python', 5), ('world', 3), ('hello', 1)] 
Nathaniel Payne
28#
Nathaniel Payne Reply to 2014-04-07 04:46:44Z
 Why not try this approach. Let us define a dictionary called mydict with the following data: mydict = {'carl':40, 'alan':2, 'bob':1, 'danny':3}  If one wanted to sort the dictionary by keys, one could do something like: for key in sorted(mydict.iterkeys()): print "%s: %s" % (key, mydict[key])  This should return the following output: alan: 2 bob: 1 carl: 40 danny: 3  On the other hand, if one wanted to sort a dictionary by value (as is asked in the question), one could do the following: for key, value in sorted(mydict.iteritems(), key=lambda (k,v): (v,k)): print "%s: %s" % (key, value)  The result of this command (sorting the dictionary by value) should return the following: bob: 1 alan: 2 danny: 3 carl: 40 
malthe
29#
 You can use a skip dict which is a dictionary that's permanently sorted by value. >>> data = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0} >>> SkipDict(data) {0: 0.0, 2: 1.0, 1: 2.0, 4: 3.0, 3: 4.0}  If you use keys(), values() or items() then you'll iterate in sorted order by value. It's implemented using the skip list datastructure.
 You can use the sorted function of Python sorted(iterable[, cmp[, key[, reverse]]]) Thus you can use: sorted(dictionary.items(),key = lambda x :x[1]) Visit this link for more information on sorted function: https://docs.python.org/2/library/functions.html#sorted
 Here is a solution using zip on d.values() and d.keys(). A few lines down this link (on Dictionary view objects) is: This allows the creation of (value, key) pairs using zip(): pairs = zip(d.values(), d.keys()). So we can do the following: d = {'key1': 874.7, 'key2': 5, 'key3': 8.1} d_sorted = sorted(zip(d.values(), d.keys())) print d_sorted # prints: [(5, 'key2'), (8.1, 'key3'), (874.7, 'key1')]