如何按值sorting字典?

我有一个从数据库中的两个字段读取的值的字典:string字段和数字字段。 string字段是唯一的,所以这是字典的关键。

我可以按键sorting,但我怎么能根据值sorting?

注意:我已经阅读了Stack Overflow问题如何通过Python中的字典值对字典列表进行sorting? 也许可以改变我的代码有一个字典的列表,但因为我真的不需要一个字典的列表,我想知道是否有一个更简单的解决scheme。

不能sorting字典,只能得到一个sorting字典的表示forms。 字典本质上是无序的,但其他types,如列表和元组,不是。 所以你需要一个sorting的表示,这将是一个列表 – 可能是一个元组列表。

例如,

 import operator x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0} sorted_x = sorted(x.items(), key=operator.itemgetter(1)) 

sorted_x将是每个元组中第二个元素sorting的元组列表。 dict(sorted_x) == x

对于那些希望按键而不是数值的人来说:

 import operator x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0} sorted_x = sorted(x.items(), key=operator.itemgetter(0)) 

如下所示: sorted(dict1, key=dict1.get)

那么,实际上可以做一个“按字典值sorting”。 最近我不得不这样做在代码高尔夫(堆栈溢出问题代码高尔夫:词频图 )。 摘要的问题是这样的:给定一个文本,计算每个单词遇到的频率,并显示一个顶级单词列表,按频率降序sorting。

如果你构造一个词典作为关键词和每个词的出现次数值,在这里简化为:

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

那么你可以得到一个单词列表,按照使用频率sorted(d, key=d.get) – sorting迭代字典键,使用单词出现次数作为sorting键。

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

我正在写这个详细的解释来说明人们通常所说的“我可以轻松地按键sorting字典,但是我怎么按价值sorting” – 我认为OP正试图解决这个问题。 解决办法是按照上面所示的值进行键列表sorting。

你可以使用:

sorted(d.items(), key=lambda x: x[1])

这将按字典中的每个条目从最小到最大的值对字典进行sorting。

字典不能sorting,但你可以从它们build立一个sorting列表。

字典值的sorting列表:

 sorted(d.values()) 

(键,值)对的列表,按值sorting:

 from operator import itemgetter sorted(d.items(), key=itemgetter(1)) 

在最近的Python 2.7中,我们有了新的OrderedDicttypes,它记住了添加项目的顺序。

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

为了从原始的一个新的有序字典,按值sorting:

 >>> from collections import OrderedDict >>> d_sorted_by_value = OrderedDict(sorted(d.items(), key=lambda x: x[1])) 

OrderedDict的行为像一个正常的字典:

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

更新:2015年12月5日使用Python 3.5

虽然我发现接受的答案很有用,但我也惊讶于它没有被更新为从标准库集合模块引用OrderedDict作为一个可行的,现代化的替代scheme – 旨在解决这种types的问题。

 from operator import itemgetter from collections import OrderedDict x = {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)]) 

官方OrderedDict文档也提供了一个非常相似的例子,但是使用lambda作为sorting函数:

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

使用namedtuple往往是非常方便的。 例如,你有一个'名字'作为键和'分数'作为值的字典,你想sorting'分数':

 import collections Player = collections.namedtuple('Player', 'score name') d = {'John':5, 'Alex':10, 'Richard': 7} 

最低分sorting第一:

 worst = sorted(Player(v,k) for (k,v) in d.items()) 

以最高得分sorting:

 best = sorted([Player(v,k) for (k,v) in d.items()], reverse=True) 

现在你可以得到名字和得分,让我们说这个第二好的球员(索引= 1)非常像Python这样的:

 player = best[1] player.name 'Richard' player.score 7 

和汉克·盖伊的回答几乎一样;


     ((key,value)在mydict.items()]中的[(value,key)

或者按照John Fouhy的build议进行优化。


    对(key,value)进行sorting((value,key)in mydict.items())

给字典

 e = {1:39, 4:34, 7:110, 2:87} 

sorting

 sred = sorted(e.items(), key=lambda value: value[1]) 

结果

 [(4, 34), (1, 39), (2, 87), (7, 110)] 

您可以使用lambda函数按值sorting,并将其存储在一个variables中,在这种情况下, 可以使用原始字典。

希望有所帮助!

在Python 2.7中,简单地做:

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

复制贴从: http : //docs.python.org/dev/library/collections.html#ordereddict-examples-and-recipes

请享用 ;-)

我有同样的问题,我解决这个问题:

 WantedOutput = sorted(MyDict, key=lambda x : MyDict[x]) 

(人们回答:“不可能sorting字典”没有读到问题!!事实上,“我可以sorting的关键,但我怎么能根据价值?”清楚地意味着他想要一个清单根据其值的值sorting的键)。

请注意订单没有被很好地定义(在输出列表中,具有相同值的键将以任意顺序)

从Python 3.6开始 ,内build字典将会被订购

好消息,所以OP的原始用例映射从数据库中检索的对具有唯一的stringid作为键和数值作为内置python v3.6 + dict的值,现在应该遵循插入顺序。

如果从数据库查询中得到2列表格expression式,如:

 SELECT a_key, a_value FROM a_table ORDER BY a_value; 

将被存储在两个python元组k_seq和v_seq(由数字索引和当然长度alignment),然后:

 k_seq = ('foo', 'bar', 'baz') v_seq = (0, 1, 42) ordered_map = dict(zip(k_seq, v_seq)) 

稍后允许输出:

 for k, v in ordered_map.items(): print(k, v) 

在这种情况下产生(对于新的Python 3.6 +内置字典!):

 foo 0 bar 1 baz 42 

在每个价值的相同的顺序。

python 3.5在我的机器上安装的地方现在会产生:

 bar 1 foo 0 baz 42 

细节:

正如Raymond Hettinger在2012年提出的(参见Python on-Python开发的主题为“更紧凑的字典,更快的迭代” ),现在(2016年),Victor Stinner在Python-dev的邮件中宣布了Python 3.6 dict压缩和获得一个私人版本;和关键字变得有序“由于修复/实施问题27350 ”紧凑和有序的字典“在Python 3.6我们现在可以使用内置的字典来维护插入顺序! !

更新 :希望这将导致薄层OrderedDict实现作为第一步。 正如@ JimFasarakis-Hilliard所指出的那样,有些人还将在未来使用OrderedDicttypes的用例。 我想整个Python社区都会仔细检查,如果这将经得起时间的考验,接下来的步骤是什么。

时间重新思考我们的编码习惯,不要错过稳定sorting开放的可能性:

  • 关键字参数和
  • (中级)字典存储

首先是因为它在一些情况下简化了函数和方法的实现。

第二,鼓励更容易使用字典作为处理pipe道中间存储。

Raymond Hettinger亲切地提供了解释“ The Python Behind Python 3.6 Dictionaries ”的文档 – 来自旧金山Python Meetup Group发布的2016-DEC-08。

也许相当一些stackoverflow高装饰问题和答案页将收到此信息的变种和许多高质量的答案将需要每个版本的更新。

买者自负:

正如@ajcr正确地指出的那样:“这个新实现的顺序保留方面被认为是一个实现细节,不应该被依赖。 (来自whatsnew36 )没有挑选, 引用被削减了一点悲观;-)。 它继续为“(这可能会在将来发生变化,但是希望在将语言规范改为强制保留所有当前和未来Python实现的语义之前,在这个语言中实现这个新的dict实现;有助于保持随机迭代顺序仍然有效的旧版本语言的向后兼容性,例如Python 3.5)。

所以,在一些人类语言(如德语)中,用法形成了语言,意志现在已经被宣布……在whatsnew36中

如果值是数字,你也可以使用集合计数器

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

这是代码:

 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 

结果如下:

原版的

 {'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} 

 {'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} 

你可以使用collections.Counter 。 请注意,这将适用于数字和非数字值。

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

你也可以创build一个“倒排索引”

 from collections import defaultdict inverse= defaultdict( list ) for k, v in originalDict.items(): inverse[v].append( k ) 

现在你的反面具有价值; 每个值都有一个适用的键列表。

 for k in sorted(inverse): print k, inverse[k] 

从技术上讲,字典不是序列,因此不能sorting。 你可以做类似的事情

 sorted(a_dictionary.values()) 

假设业绩不是很大。

更新:感谢评论者指出,我在一开始就这样做太复杂了。

为什么不尝试这种方法。 让我们用以下数据定义一个名为mydict的字典:

 mydict = {'carl':40, 'alan':2, 'bob':1, 'danny':3} 

如果想用键来sorting字典,可以这样做:

 for key in sorted(mydict.iterkeys()): print "%s: %s" % (key, mydict[key]) 

这应该返回以下输出:

 alan: 2 bob: 1 carl: 40 danny: 3 

另一方面,如果有人想按照价值对字典进行sorting(就像问题中提到的那样),我们可以做下面的事情:

 for key, value in sorted(mydict.iteritems(), key=lambda (k,v): (v,k)): print "%s: %s" % (key, value) 

该命令的结果(按值sorting字典)应返回以下内容:

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

你可以使用一个跳跃词典 ,它是一个永久按值sorting的词典。

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

如果你使用keys()values()或者items()那么你将按照值的顺序迭代。

它使用跳过列表数据结构来实现。

这将返回字典中键值对的列表,按照从最高到最低的值sorting:

 sorted(d.items(), key=lambda x: x[1], reverse=True) 

对于按键sorting的字典,请使用以下命令:

 sorted(d.items(), reverse=True) 

返回是元组列表,因为字典本身不能sorting。

这可以打印或发送到进一步的计算。

使用字典中的 ValueSortedDict

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

您还可以使用可以传递给键的自定义函数。

 def dict_val(x): return x[1] x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0} sorted_x = sorted(x.items(), key=dict_val) 

还有一种方法是使用labmda函数

 x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0} sorted_x = sorted(x.items(), key=lambda t: t[1]) 

迭代一个字典并按值降序排列:

 $ 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 

如果你的值是整数,而你使用Python 2.7或更新的版本,你可以使用collections.Counter而不是dictmost_common方法会给你所有的项目,按值sorting。

这在3.1.x中工作:

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

我想出了这个,

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

对于Python 3.x: x.items()replaceiteritems()

 >>> sorted_x {0: 0, 1: 2, 2: 1, 3: 4, 4: 3} 

或尝试与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])) 

你可以使用Python的sorting函数

sorted(iterable[, cmp[, key[, reverse]]])

因此您可以使用:

sorted(dictionary.items(),key = lambda x :x[1])

请访问此链接以获取有关已sorting函数的更多信息: https : //docs.python.org/2/library/functions.html#sorted

这是一个在d.values()d.keys()上使用zip的解决scheme。 这个链接(在字典视图对象上)的几行是:

这允许使用zip()创build(值,键)对:pairs = zip(d.values(),d.keys())。

所以我们可以做到以下几点:

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

为了完整起见,我使用heapq发布了一个解决scheme。 请注意,此方法将适用于数字和非数字值

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