简体   繁体   English

在 Python 字典中排序 function

[英]Sorted function in Python dictionary

I have a dictionary and I need to print the contents of dictionary first sorted by "value" if there is any value tie then I need to use "key" as a tie breaker so that the keys that have the identical values will be printed in alphabetic order.我有一本字典,如果有任何值平局,我需要打印首先按“值”排序的字典内容,然后我需要使用“键”作为平局断路器,以便打印具有相同值的键字母顺序。

final = OrderedDict(sorted(mydict.items(), key=lambda x: (x[1], x[0]), reverse=True))

for key, value in final.items():
    print(f'{key} : {value}')

but when the print command runs, it will display the output like the identical values have not been sorted as expected:但是当打印命令运行时,它将显示 output 就像没有按预期排序相同的值:

Action : 3
Romance : 2
Horror : 2
History : 2
Comedy : 2
Adventure : 1

The way it's supposed to print must be like:它应该打印的方式必须是这样的:

Action : 3
Comedy : 2
History : 2
Horror : 2
Romance : 2
Adventure : 1

Any thoughts about how can I correct this issue?关于如何纠正这个问题的任何想法?

{k: v for k, v in sorted(mydict.items(), key=lambda item: (-item[1], item[0]), reverse=False)}

reverse is applied after the sequence has been sorted according to key .在根据key对序列进行排序应用reverse You only want the comparison on x[1] to be reversed, not the final ordering.您只希望x[1]上的比较被反转,而不是最终排序。 I would use functools.cmp_to_key to convert a comparison function to a key function.我将使用functools.cmp_to_key将比较 function 转换为密钥 function。

from functools import cmp_to_key

# Redefined from Python 2 since Python 3 dropped it
def cmp(x, y):
    return -1 if x < y else 0 if x == y else 1

def genre_sort(x, y):
    # A bigger count is a smaller genre; otherwise, sort alphabetically
    # by name
    return cmp(y[1], x[1]) or cmp(x[0], y[0])
    
final = OrderedDict(sorted(mydict.items(), key=cmp_to_key(genre_sort)))

You want to reverse the sort for x[1] only so don't pass reverse=True here, instead use negative number trick:您只想反转x[1]的排序,所以不要在这里传递reverse=True ,而是使用负数技巧:

final = OrderedDict(sorted(mydict.items(), key=lambda x: (-x[1], x[0])))

Why this answer when there are already three other ones?当已经有其他三个答案时,为什么要这个答案?

In my opinion none of the other answers exposed the core of the problem described in the question, which is by the way already sufficiently answered here: https://stackoverflow.com/questions/20145842/python-sorting-by-multiple-criteria and here https://stackoverflow.com/questions/55866762/how-to-sort-a-list-of-strings-in-reverse-order-without-using-reverse-true-parame making it a candidate for becoming closed as a duplicate.在我看来,其他答案都没有暴露问题中描述的问题的核心,顺便说一句,这里已经充分回答了:https://stackoverflow.com/questions/20145842/python-sorting-by-multiple-criteria 在这里 https://stackoverflow.com/questions/55866762/how-to-sort-a-list-of-strings-in-reverse-order-without-using-reverse-true-parame使其成为关闭的候选者作为副本。

The feature of Python allowing to have a solution to the problem of sorting columns in different sorting orders is the fact that Python 的特点是可以解决以不同排序顺序对列进行排序的问题,即

Python's sort is stable allowing you to use consecutive sorts, using the rightmost criteria first, then the next, etc. ( Martijn Pieters ) . Python 的排序是稳定的,允许您使用连续排序,首先使用最右边的标准,然后是下一个,依此类推(Martijn Pieters)

That Python's sort algorithm is stable means that equal elements keep their relative order. Python 的排序算法是稳定的,这意味着相等的元素保持它们的相对顺序。 So you can use a first sort on the second element (sorting in ascending order) and then sort again, on only the first element and in reverse order.因此,您可以对第二个元素使用第一次排序(按升序排序),然后再次排序,仅对第一个元素并以相反的顺序排序。

I have changed the dictionary listed in the question to having only string values what will not allow to use the 'trick' with negative number values in the key function to achieve the desired result to demonstrate what is said above.我已将问题中列出的字典更改为仅包含字符串值,不允许在键 function 中使用带有负数值的“技巧”,以实现所需的结果来演示上述内容。

The code below:下面的代码:

mydict = { 
    'Romance'   : '2', 
    'Adventure' : '1', 
    'Action'    : '3', 
    'Horror'    : '2', 
    'History'   : '2',
    'Comedy'    : '2',
}
mylist = list(mydict.items())
print(mylist)
print()
mylist = sorted(mylist)
print(mylist)
mslist = sorted(mylist, key=lambda x: (x[1]), reverse=True)
print(mslist)
from collections import OrderedDict
final = OrderedDict(mslist)
for key, value in final.items():
    print(f'  {key:10} : {value}')

creating following output:创建以下 output:

[('Romance', '2'), ('Adventure', '1'), ('Action', '3'), ('Horror', '2'), ('History', '2'), ('Comedy', '2')]

[('Action', '3'), ('Adventure', '1'), ('Comedy', '2'), ('History', '2'), ('Horror', '2'), ('Romance', '2')]
[('Action', '3'), ('Comedy', '2'), ('History', '2'), ('Horror', '2'), ('Romance', '2'), ('Adventure', '1')]
  Action     : 3
  Comedy     : 2
  History    : 2
  Horror     : 2
  Romance    : 2
  Adventure  : 1

demonstrates what I am speaking about here.展示了我在这里所说的内容。

From:从:

[('Action', '3'), ('Adventure', '1'), ('Comedy', '2'), ('History', '2'), ('Horror', '2'), ('Romance', '2')]
[('Action', '3'), ('Comedy', '2'), ('History', '2'), ('Horror', '2'), ('Romance', '2'), ('Adventure', '1')]

can be seen that the second sort moves only '('Adventure', '1')' keeping the order of all the other items.可以看出,第二个排序仅移动'('Adventure', '1')'保持所有其他项目的顺序。

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

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