简体   繁体   English

排序python字典,其中“值”作为主键,“键”作为辅助键

[英]Sort python dictionaries with 'value' as primary key and 'key' as secondary

What I am trying to do here is to display characters according to number of occurrences in a string in descending order. 我在这里尝试做的是根据字符串中出现的次数以降序显示字符。 If two characters share the same number of occurrences, then they should be displayed as per the alphabetic order. 如果两个字符共享相同的出现次数,则应按照字母顺序显示它们。

So given a string, 'abaddbccdd', what I want to display as output is: ['d', 'a', 'b', 'c'] 因此,给定字符串“ abaddbccdd”,我要显示为输出的内容是:['d','a','b','c']

Here is what I have done so far: 到目前为止,这是我所做的:

>>> from collections import Counter
>>> s = 'abaddbccdd'
>>> b = Counter(s)
>>> b
Counter({'d': 4, 'a': 2, 'c': 2, 'b': 2})
>>> b.keys()
['a', 'c', 'b', 'd']
>>> c = sorted(b, key=b.get, reverse=True)
>>> c
['d', 'a', 'c', 'b']
>>>

But how to handle the second part? 但是如何处理第二部分? 'a', 'b' and 'c' all appear in the text exactly twice and are out of order. “ a”,“ b”和“ c”在文本中都出现了两次,并且顺序不正确。 What is the best way (hopefully shortest too) to do this? 什么是最好的方法(希望也是最短的方法)?

The shortest way is: 最短的方法是:

>>> sorted(sorted(b), key=b.get, reverse=True)
['d', 'a', 'b', 'c']

So sort the sequence once in its natural order (the key order) then reverse sort on the values. 因此,按自然顺序(键顺序)对序列进行一次排序,然后对值进行反向排序。

Note this won't have the fastest running time if the dictionary is large as it performs two full sorts, but in practice it is probably simplest because you want the values descending and the keys ascending. 请注意,如果字典很大,因为它执行两种完整排序,则运行时间不会最快,但是实际上,这可能是最简单的,因为您希望值递减而键递增。

The reason it works is that Python guarantees the sort to be stable. 它起作用的原因是Python保证排序是稳定的。 That means when the keys are equal the original order is preserved, so if you sort repeatedly from the last key back to the first you will get the desired result. 这意味着当键相等时,将保留原始顺序,因此,如果您从最后一个键重复排序到第一个键,则将获得所需的结果。 Also reverse=True is different than just reversing the output as it also respects stability and only reverses the result where the keys are different. 另外, reverse=True与仅反转输出不同,因为它也尊重稳定性,并且仅在键不同的情况下反转结果。

This can be done in a single sorting pass. 这可以通过一次排序就可以完成。 The trick is to do an ascending sort with the count numbers negated as the primary sorting key and the dictionary's key strings as the secondary sorting key. 诀窍是进行升序排序,将计数数字取为主要排序关键字,将字典的关键字字符串取为次要排序关键字。

b = {'d': 4, 'a': 2, 'c': 2, 'b': 2}
c = sorted(b, key=lambda k:(-b[k], k))
print(c)

output 产量

['d', 'a', 'b', 'c']

If you are already using a Counter object, there is the Counter.most_common method. 如果您已经在使用Counter对象,则可以使用Counter.most_common方法。 This will return a list of the items in order of highest to lowest frequency. 这将按频率从高到低的顺序返回项目列表。

>>> b.most_common()
[('d', 4), ('a', 2), ('b', 2), ('c', 2)]

您可以使用lambda函数:

>>> sorted(b, key=lambda char: (b.get(char), 1-ord(char)), reverse=True)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM