Python 3 按其值对字典进行排序
Posted
技术标签:
【中文标题】Python 3 按其值对字典进行排序【英文标题】:Python 3 sort a dict by its values 【发布时间】:2014-01-23 12:47:51 【问题描述】:我发现的唯一方法适用于 python2 或仅返回元组列表。
是否可以对字典进行排序,例如"aa": 3, "bb": 4, "cc": 2, "dd": 1
,通过它的价值观?
我想要实现的排序字典的顺序是从大到小。我希望结果如下所示:
bb 4
aa 3
cc 2
dd 1
排序后我想将它存储到一个文本文件中。
【问题讨论】:
【参考方案1】:itemgetter
(见其他答案)(据我所知)对于大型字典更有效,但对于常见情况,我相信d.get
获胜。而且它不需要额外的import
。
>>> d = "aa": 3, "bb": 4, "cc": 2, "dd": 1
>>> for k in sorted(d, key=d.get, reverse=True):
... k, d[k]
...
('bb', 4)
('aa', 3)
('cc', 2)
('dd', 1)
请注意,您也可以将d.__getitem__
设置为key
函数,这可能会比d.get
提供小的性能提升。
【讨论】:
能否解释一下|展开第 2 行的语法?我刚刚学习 Python 3,很想了解这个。 当然,但如果我知道你不明白的地方会更容易。[x for x in iterable]
是一个 Python List Comprehension (google),它在 Python 中创建列表非常常见且高效。 (k, d[k])
是一个双元素元组,第二个元素 (d[k]
) 是字典中的值。 sorted()
是一个内置函数,返回按值排序的字典键。使用key=d.get
它是我的答案的关键,这并不容易知道。了解内置函数是必不可少的。我希望这会有所帮助。
谢谢! [x for x in iterable]
“列表理解”是介绍课程中缺少的内容。现在阅读它(很难找到不知道名字的)。
我通过最后一次编辑使代码更简单,完全消除了列表理解。【参考方案2】:
from collections import OrderedDict
from operator import itemgetter
d = "aa": 3, "bb": 4, "cc": 2, "dd": 1
print(OrderedDict(sorted(d.items(), key = itemgetter(1), reverse = True)))
打印
OrderedDict([('bb', 4), ('aa', 3), ('cc', 2), ('dd', 1)])
尽管从您的最后一句话来看,元组列表似乎可以正常工作,例如
from operator import itemgetter
d = "aa": 3, "bb": 4, "cc": 2, "dd": 1
for key, value in sorted(d.items(), key = itemgetter(1), reverse = True):
print(key, value)
打印出来的
bb 4
aa 3
cc 2
dd 1
【讨论】:
感谢您的帮助。我认为其中一个解决方案将与此类似。dict
现在保持插入顺序,因此没有理由使用OrderedDict
我可以想到两个原因,首先它明确表明您关心订单,其次有人可能会在较旧的解释器上运行您的代码,并且让它默默地行为不端并不是一个好的结果。【参考方案3】:
您可以使用dictionary comprehension以反向顺序(从大到小)按值排序:
k: d[k] for k in sorted(d, key=d.get, reverse=True)
# 'b': 4, 'a': 3, 'c': 2, 'd': 1
如果您想按值升序(从小到大)排序
k: d[k] for k in sorted(d, key=d.get)
# 'd': 1, 'c': 2, 'a': 3, 'b': 4
如果要按键升序排序
k: d[k] for k in sorted(d)
# 'a': 3, 'b': 4, 'c': 2, 'd': 1
这适用于 CPython 3.6+ 和 Python 3.7+ 的任何实现,因为字典保持插入顺序。
【讨论】:
【参考方案4】:另一种方法是使用 lambda 表达式。根据解释器版本以及您是否希望创建排序字典或排序键值元组(如 OP 所做的那样),这甚至可能比接受的答案更快。
d = 'aa': 3, 'bb': 4, 'cc': 2, 'dd': 1
s = sorted(d.items(), key=lambda x: x[1], reverse=True)
for k, v in s:
print(k, v)
【讨论】:
虽然您的代码可以正常工作,但我认为字典不能保证按照添加的顺序返回项目。 @Ivan 谢谢——我已经删除了这里多余的 dict() 用法,尽管在 CPython 3.6+ 中,dict 是保持顺序的,这很可能在不久的将来成为一种语言特性(docs.python.org/3/whatsnew/3.6.html) 谢谢,很高兴知道。另外 - 最后你可以只做print(s)
而不是循环:)
dict
s 保留从 3.7 开始的所有 Python 的顺序
实际上它不到 10%,我在 Python 3.8.6 上用 100,000 个元素的字典得到 54 毫秒和 57.3 毫秒,但在技术上仍然较慢。我认为您应该删除它们,这不是值得优化的。【参考方案5】:
要对字典进行排序,我们可以使用 operator 模块。 Here 是操作员模块文档。
import operator #Importing operator module
dc = "aa": 3, "bb": 4, "cc": 2, "dd": 1 #Dictionary to be sorted
dc_sort = sorted(dc.items(),key = operator.itemgetter(1),reverse = True)
print dc_sort
输出序列将是一个排序列表:
[('bb', 4), ('aa', 3), ('cc', 2), ('dd', 1)]
如果我们想对键进行排序,我们可以使用
dc_sort = sorted(dc.items(),key = operator.itemgetter(0),reverse = True)
输出序列将是:
[('dd', 1), ('cc', 2), ('bb', 4), ('aa', 3)]
【讨论】:
Paul Draper 的回答已经在使用 Operator...只是没有导入完整的库【参考方案6】:要对字典进行排序并在之后保持它作为字典的功能,您可以使用标准库中的OrderedDict。
如果这不是您所需要的,那么我鼓励您重新考虑给您留下元组列表的排序函数。如果不是键值对(元组)的有序列表,您想要什么输出?
【讨论】:
dict
现在保持插入顺序,因此没有理由使用OrderedDict
以上是关于Python 3 按其值对字典进行排序的主要内容,如果未能解决你的问题,请参考以下文章
java 根据其值对地图进行排序。资料来源:http://stackoverflow.com/a/2581754/1057348