博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python sort dict by value
阅读量:4029 次
发布时间:2019-05-24

本文共 21000 字,大约阅读时间需要 70 分钟。

Whilst I found the accepted answer useful, I was also surprised that it hasn't been updated to reference  from the standard library collections module as a viable, modern alternative - designed to solve exactly this type of problem.

from operator import itemgetterfrom collections import OrderedDictx = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}sorted_x = OrderedDict(sorted(x.items(), key=itemgetter(1)))# OrderedDict([(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)])

The official  documentation offers a very similar example too, but using a lambda for the sort function:

# regular unsorted dictionaryd = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2}# dictionary sorted by valueOrderedDict(sorted(d.items(), key=lambda t: t[1]))# OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])

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 a sorted representation, which will be a list—probably a list of tuples.

For instance,

import operatorx = {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 operatorx = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}sorted_x = sorted(x.items(), key=operator.itemgetter(0))

 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  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.

 
4  
The dictionary data structure does not have inherent order. You can iterate through it but there's nothing to guarantee that the iteration will follow any particular order. This is by design, so your best bet is probaly using anohter data structure for representation. –   
Jul 5 '10 at 2:08
57  
"sorted()" can operate on dictionaries (and returns a list of sorted keys), so I think he's aware of this. Without knowing his program, it's absurd to tell someone they're using the wrong data structure. If fast lookups are what you need 90% of the time, then a dict is probably what you want. –   
Feb 15 '13 at 19:04
2  
For those suggesting that this is a duplicate of  , that question is marked as a duplicate of this question. –   
Sep 18 '13 at 16:36
3  
If possible, instantiate a NumPy Series from the dictionary and sort it using pandas.Series.order –   
Nov 27 '14 at 14:22

34 Answers

1
1903
accepted
+500

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 a sorted representation, which will be a list—probably a list of tuples.

For instance,

import operatorx = {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 operatorx = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}sorted_x = sorted(x.items(), key=operator.itemgetter(0))
 
23  
for timings on various dictionary sorting by value schemes:   –   
Mar 14 '09 at 17:55
59  
sorted_x.reverse() will give you a descending ordering (by the second tuple element) – 
May 3 '10 at 5:24
176  
saidimu: Since we're already using sorted(), it's much more efficient to pass in the reverse=Trueargument. –   
Jul 5 '10 at 2:59
57  
In python3 I used a lambda: sorted(d.items(), key=lambda x: x[1]). Will this work in python 2.x? –   
Feb 15 '11 at 15:05
53  
OrderedDict added to collections in 2.7. Sorting example shown at:  –   
Apr 24 '11 at 6:31 
583

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 ). Abridged, the problem was of the kind: given a text, count how often each word is encountered and display list of the top words, sorted by decreasing frequency. 

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

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

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

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

I am writing this detailed explanation to illustrate what do 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.

 
10  
This is also good but key=operator.itemgetter(1) should be more scalable for efficiency than key=d.get –   
Dec 9 '11 at 21:18
3  
You will first need to: import collections # to use defaultdict –   
Apr 12 '13 at 23:13 
3  
@raylu I do observe a "does not work" behaviour using itemgetter: -----  from operator import itemgetter d = {"a":7, "b":1, "c":5, "d":3} sorted_keys = sorted(d, key=itemgetter, reverse=True) for key in sorted_keys: print "%s: %d" % (key, d[key]) ----- -> b: 1 c: 5 a: 7 d: 3 The results change each time I run the code: weird. (sorry, can't get the code to display properly) –   
Aug 13 '14 at 15:58 
3  
@bli sorted_keys = sorted(d.items(), key=itemgetter(1), reverse=True) and for key, val in sorted_keys: print "%s: %d" % (key, val) - itemgetter creates a function when it's called, you don't use it directly like in your example. And a plain iteration on a dict uses the keys without the values –   
Aug 19 '14 at 20:21 
293

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.

 
32  
+1 For being the cleanest solution. However it doesn't sort the dictionary (hash table, not possible), rather it returns an ordered list of (key, value) tuples. –   
Feb 15 '11 at 15:10 
1  
@Keyo I'm new to python and came across the need to sort a dictionary. And I want to make sure I understood you well: there is no way to use lambda to sort a dictionary, right? –   
Jan 9 '13 at 4:20
14  
I'd prefer key=lambda (k, v): v personally –   
Apr 9 '15 at 23:08 
4  
@Claudiu I like that (k, v) syntax too, but it's not available in Python 3 where was removed. –   
Feb 5 at 17:53
101

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 itemgettersorted(d.items(), key=itemgetter(1))
 
5  
+1: sorted(d.values()) is easier to read/understand than Nas's sorted(dict1, key=dict1.get), and therefore more Pythonic. About readability, please also consider my  suggestion. –   
Aug 30 '11 at 23:42
12  
@Remi, those are two different things! sorted(d.values()) returns sorted list of the values from the dictionary, where sorted(d, key=d.get) returns list of the keys, sorted in order of the values! Way different. If you don't see the need for the latter, read my post above for "real life" example –   
Feb 11 '13 at 6:39
70

In recent Python 2.7, we have the new  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: 2fourth: 4third: 3first: 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: 1second: 2third: 3fourth: 4>>> d_sorted_by_valueOrderedDict([('first': 1), ('second': 2), ('third': 3), ('fourth': 4)])
 
1  
This is not what the question is about - it is not about maintaining order of keys but about "sorting by value" –   
Jul 5 '10 at 7:07
5  
@Nas Banov: it is NOT sorting by the key. it is sorting in the order, we create the items. in our case, we sort by the value. unfortunately, the 3-item dict was unfortunately chosen so the order was the same, when sorted voth by value and key, so i expanded the sample dict. –   
Jul 5 '10 at 10:56
31

It can often be very handy to use . For example, you have a dictionary of 'name' as keys and 'score' as values and you want to sort on 'score':

import collectionsPlayer = 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
 
28

Pretty much the same as Hank Gay's answer;

sorted([(value,key) for (key,value) in mydict.items()])
 
5  
..and as with Hank Gay's answer, you don't need the square brackets. sorted() will happily take any iterable, such as a generator expression. –   
Mar 5 '09 at 1:45
20

In Python 2.7, simply do:

from collections import OrderedDict# regular unsorted dictionaryd = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2}# dictionary sorted by keyOrderedDict(sorted(d.items(), key=lambda t: t[0]))OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])# dictionary sorted by valueOrderedDict(sorted(d.items(), key=lambda t: t[1]))OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])

copy-paste from : 

Enjoy ;-)

 
18

I had the same problem, 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)

 
15

You can use the . 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)])
 
3  
How is this different from ? –   
Apr 3 '14 at 17:07
15

UPDATE: 5 DECEMBER 2015 using Python 3.5

Whilst I found the accepted answer useful, I was also surprised that it hasn't been updated to reference  from the standard library collections module as a viable, modern alternative - designed to solve exactly this type of problem.

from operator import itemgetterfrom collections import OrderedDictx = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}sorted_x = OrderedDict(sorted(x.items(), key=itemgetter(1)))# OrderedDict([(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)])

The official  documentation offers a very similar example too, but using a lambda for the sort function:

# regular unsorted dictionaryd = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2}# dictionary sorted by valueOrderedDict(sorted(d.items(), key=lambda t: t[1]))# OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])
 
13

You can create an "inverted index", also

from collections import defaultdictinverse= 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]
 
13

If values are numeric you may also use Counter from collections

from collections import Counterx={'hello':1,'python':5, 'world':3}c=Counter(x)print c.most_common()>> [('python', 5), ('world', 3), ('hello', 1)]
 
9

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.

UPDATE: Thanks to the commenters for pointing out that I made this way too complicated in the beginning.

 
8
from django.utils.datastructures import SortedDictdef 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
 
1  
question was: sort by value, not by keys... I like seeing a function. You can import collections and of course use sorted(data.values()) –   
Aug 30 '11 at 0:38
8

This is the code:

import operatororigin_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 fooprint "\n>> Rofl sort >>"for foo in sorted(origin_list, key=operator.itemgetter("rofl")):    print fooprint "\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}
 
7

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: 2bob: 1carl: 40danny: 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: 1alan: 2danny: 3carl: 40
 
7

You can use a  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  datastructure.

 
5

Use ValueSortedDict from :

from dicts.sorteddict import ValueSortedDictd = {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)]
 
5

If your values are integers, and you use Python 2.7 or newer, you can use instead of dict. The most_common method will give you all items, sorted by the value.

 
4

Iterate through a dict and sort it by its values in descending order:

$ python --versionPython 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 5tuli 4joka 3sana 2siis 1
 
4

This works in 3.1.x:

import operatorslovar_sorted=sorted(slovar.items(), key=operator.itemgetter(1), reverse=True)print(slovar_sorted)
 
4

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: 

 
4

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.

 
1  
There is shorter and faster way to do what you are trying: sorted(d.items(), reverse=True) –   
Feb 20 '14 at 20:17
3

For the sake of completeness, I am posting a solution using . 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)]
 
3

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 OrderedDictod1 = OrderedDict(sorted(x.items(), key=lambda t: t[1]))
 
3

Here is a solution using zip on . 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')]
 
3
>>> e = {1:39, 4:34, 7:110, 2:87}>>> sortE = sorted(e.items(), key=lambda value: value[1])>>> print(sortE)[(4, 34), (1, 39), (2, 87), (7, 110)]

You can use a lambda function to sort things up by value and store them processed inside a variable, in this case sortE with e the original dictionary.

Best Regards. 

 
2
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
 
1

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

转载地址:http://nohbi.baihongyu.com/

你可能感兴趣的文章
WPF UI&控件免费开源库
查看>>
QT打开项目提示no valid settings file could be found
查看>>
Win10+VS+ESP32环境搭建
查看>>
Ubuntu+win10远程桌面
查看>>
flutter-实现圆角带边框的view(android无效)
查看>>
flutter-实现一个下拉刷新上拉加载的列表
查看>>
android 代码实现圆角
查看>>
flutter-解析json
查看>>
android中shader的使用
查看>>
java LinkedList与ArrayList迭代器遍历和for遍历对比
查看>>
Android DataBinding使用2-Recycleview
查看>>
drat中构造方法
查看>>
JavaScript的一些基础-数据类型
查看>>
JavaScript基础知识(2)
查看>>
转载一个webview开车指南以及实际项目中的使用
查看>>
android中对于非属性动画的整理
查看>>
一个简单的TabLayout的使用
查看>>
关于let{a}=B出现的解构赋值
查看>>
ReactNative使用Redux例子
查看>>
Promise的基本使用
查看>>