Python 3通过其值对字典进行排序


78

我发现的唯一方法适用于python2或仅返回元组列表。

是否可以按字典{"aa": 3, "bb": 4, "cc": 2, "dd": 1}的值对字典进行排序?

我要实现的字典排序顺序是从最大到最小。我希望结果看起来像这样:

bb 4
aa 3
cc 2
dd 1

排序后,我想将其存储到文本文件中。

Answers:


119

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


1
您能否解释一下|扩展第2行中的语法?我只是在学习Python 3,很想了解这一点。
Serge

2
当然可以,但是如果我知道您不了解的内容,会更容易。[x for x in iterable]是Python列表推导(google),在Python中创建列表非常普遍且有效。(k, d[k])是两个元素的元组,第二个元素(d[k])是字典中的值。sorted()是一个内置函数,返回按值排序的字典键。使用key=d.get它,我的答案的关键是不容易知道的。了解内置功能至关重要。希望对您有所帮助。
SzieberthAdam

谢谢!在[x for x in iterable]“列表理解”是什么在介绍过程中丢失。现在开始阅读(很难找到不知道名字的地方)。
Serge

29
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

谢谢你的帮助。我认为解决方案之一将与此类似。

1
dict现在保留广告订单,因此没有理由使用OrderedDict
Boris

1
我可以想到两个原因,首先,它可以使您明确地关心命令;其次,有人可以在较旧的解释器上运行您的代码,并且使其默默地表现不佳。
–plugwash

16

您可以使用字典理解相反的顺序对进行排序(从最大到最小):

{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+的任何实现,因为字典保持插入顺序。


11

另一种方法是使用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)

1
当您的代码有效时,我认为字典不能保证以与添加顺序相同的顺序返回项目。
伊万

2
@Ivan谢谢–我在这里删除了dict()的多余用法,尽管在CPython 3.6+中,dict是保持顺序的,并且在不久的将来有可能成为语言功能(docs.python.org/3 /whatsnew/3.6.html
贝德康斯坦丁尼

谢谢,很有趣。另外-最后,您只需要执行print(s)一个循环即可:)
Ivan

1
dicts从3.7开始的所有Python中的保留顺序
Boris

1
实际上它还不到10%,在100,000个元素字典的Python 3.8.6上,我得到了54毫秒,而57.3毫秒得到了57.3毫秒,但是从技术上来说还是比较慢的。我认为您应该删除它们,这不是一个值得的优化。
鲍里斯

10

要对字典进行排序,我们可以使用运算符模块。是操作员模块文档。

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 ...只是不导入完整的库
Salvatore Cosentino

0

要对字典进行排序并使其随后继续充当字典,可以使用标准库中的OrderedDict

如果那不是您所需要的,那么我建议您重新考虑使您有元组列表的sort函数。您想要什么输出,如果不是键-值对(元组)的有序列表?


dict现在保留插入顺序,因此没有理由使用OrderedDict
Boris
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.