Python 3按其值对dict进行排序

64 python sorting dictionary python-3.x

我发现的唯一方法是为python2工作或仅返回元组列表.

是否可以对字典进行排序,例如{"aa": 3, "bb": 4, "cc": 2, "dd": 1},通过其值?

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

bb 4
aa 3
cc 2
dd 1
Run Code Online (Sandbox Code Playgroud)

排序后我想将它存储到文本文件中.

Szi*_*dam 98

itemgetter(参见其他答案)(对我来说)对于大型词典更有效,但对于常见情况,我相信d.get胜利.它不需要额外的import.

>>> d = {"aa": 3, "bb": 4, "cc": 2, "dd": 1}
>>> s = [(k, d[k]) for k in sorted(d, key=d.get, reverse=True)]
>>> for k, v in s:
...     k, v
...
('bb', 4)
('aa', 3)
('cc', 2)
('dd', 1)
Run Code Online (Sandbox Code Playgroud)

请注意,您也可以将其设置d.__getitem__key可以提供较小性能提升的功能d.get.

  • 当然但如果我知道你不明白的东西会更容易.`[x for x in iterable]`是一个Python List Comprehension(google),它在Python中创建列表非常常见和高效.`(k,d [k])`是一个双元素元组,第二个元素(`d [k]`)是字典中的值.`sorted()`是一个内置函数,返回按值排序的字典键.使用`key = d.get`这是我的答案的关键,这是不容易知道的.了解内置功能至关重要.我希望这有帮助. (2认同)

Pau*_*per 27

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)))
Run Code Online (Sandbox Code Playgroud)

版画

OrderedDict([('bb', 4), ('aa', 3), ('cc', 2), ('dd', 1)])
Run Code Online (Sandbox Code Playgroud)

虽然从你的最后一句话来看,似乎元组列表可以正常工作,例如

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)
Run Code Online (Sandbox Code Playgroud)

打印

bb 4
aa 3
cc 2
dd 1
Run Code Online (Sandbox Code Playgroud)

  • 我可以想到两个原因,首先它明确表明您关心顺序,其次有人可能会在较旧的解释器上运行您的代码并且让它默默地行为不端并不是一个好结果。 (2认同)

Bor*_*ris 22

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

{k: d[k] for k in sorted(d, key=d.get, reverse=True)}
# {'b': 4, 'a': 3, 'c': 2, 'd': 1}
Run Code Online (Sandbox Code Playgroud)

如果要按升序(从小到大)按排序

{k: d[k] for k in sorted(d, key=d.get)}
# {'d': 1, 'c': 2, 'a': 3, 'b': 4}
Run Code Online (Sandbox Code Playgroud)

如果要按键升序排序

{k: d[k] for k in sorted(d)}
# {'a': 3, 'b': 4, 'c': 2, 'd': 1}
Run Code Online (Sandbox Code Playgroud)

这适用于 CPython 3.6+ 和 Python 3.7+ 的任何实现,因为字典保持插入顺序。


Rec*_*eck 8

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

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
Run Code Online (Sandbox Code Playgroud)

输出序列将是一个排序列表:

[('bb', 4), ('aa', 3), ('cc', 2), ('dd', 1)]
Run Code Online (Sandbox Code Playgroud)

如果我们想对键进行排序,我们可以使用

dc_sort = sorted(dc.items(),key = operator.itemgetter(0),reverse = True)
Run Code Online (Sandbox Code Playgroud)

输出顺序为:

[('dd', 1), ('cc', 2), ('bb', 4), ('aa', 3)]
Run Code Online (Sandbox Code Playgroud)


Bed*_*des 7

一种更简单(且快10%)的方法是使用lambda表达式

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)
Run Code Online (Sandbox Code Playgroud)

时机

%%timeit在CPython 3.7上使用print(k, v)替换,pass以使IO不受影响。

使用d.get()接受的答案:

1.19 µs ± 16.3 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
Run Code Online (Sandbox Code Playgroud)

Lambda表达式:

1.07 µs ± 10.7 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
Run Code Online (Sandbox Code Playgroud)

  • @Ivan 谢谢——我在这里删除了 dict() 的多余使用,尽管在 CPython 3.6+ 中,dict 是顺序保留的,这很可能在不久的将来成为一种语言功能(https://docs.python .org/3/whatsnew/3.6.html) (2认同)