Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:使用自定义比较器进行有序排序_Python - Fatal编程技术网

Python:使用自定义比较器进行有序排序

Python:使用自定义比较器进行有序排序,python,Python,我有一本字典,内容如下: dict = {'P1' :361 , 'P2' : 361, 'P3' : 391, 'P6' : 361, 'P4':361, 'P5' :361} 需要根据值按降序排序。对于任何给定项,如果值与比较的项相同,则应按键的升序排序。因此,dict的结果值应为 {'P3' : 391 , 'P1' : 361, 'P2': 361, 'P4': 361, 'P5': 361,'P6' : 361} 我使用以下方法完成了第一部分: sorted_dict = Orde

我有一本字典,内容如下:

dict = {'P1' :361 , 'P2' : 361, 'P3' : 391, 'P6' : 361, 'P4':361, 'P5' :361}
需要根据值按降序排序。对于任何给定项,如果值与比较的项相同,则应按键的升序排序。因此,dict的结果值应为

{'P3' : 391 , 'P1' : 361, 'P2': 361, 'P4': 361, 'P5': 361,'P6' : 361}
我使用以下方法完成了第一部分:

sorted_dict = OrderedDict(sorted(dict.items(), key=lambda t: t[1],reverse=True))
然而,我不确定如何超越这一点。我假设比较器函数通常可以是这样的

def comparator(item1,item2):
    if item1.value() == item2.value():
        if item1.key()<item2.key():
            return -1
        if item1.key()>item2.key():
            return 1
        if item1.key() == item2.key():
            return 0
    if item1.value() < item2.value():
        return -1
    if item1.value() > item2.value():
        return 1
def比较器(项目1、项目2):
如果item1.value()==item2.value():
如果item1.key()item2.key():
返回1
如果item1.key()==item2.key():
返回0
如果item1.value()item2.value():
返回1

我不确定如何实施这一点。请原谅我的天真,我是Python的初学者,对该语言的编程结构知之甚少

您可以使用稍微不同的lambda表达式作为排序键

sorted_dict = OrderedDict(sorted(dict.items(), key=lambda x: (-x[1], x[0])))
输出

OrderedDict([('P3', 391), ('P1', 361), ('P2', 361), ('P4', 361), ('P5', 361), ('P6', 361)])

提供一个
就是提供一个函数来在比较之前转换每个项目。所以这里,匿名lambda函数提供了一个用于排序的序列转换-序列通过依次比较每个元素来排序。因此,我们按数字的负数排序(以反转自然升序->降序),如果比较相等,我们将转到字符串进行排序,它通常按照您希望的方式进行排序(至少对于提供的示例)。如果字典排序不能给出预期的结果,您可能需要在字符串中使用for更大的数字

如果键不包含所有的单位数,并且您不需要按字典排序,则需要添加更多逻辑:

d = {'P1000': 361, 'P200': 361, 'P3': 391, 'P6': 361, 'P4': 361, 'P5': 361,"P100":361}
import re

patt = re.compile("[^\d]")


def cmp(x):
     letts = patt.search(x).group()
     return patt.search(x).group(), int(x[len(letts):])
您可以使用以下示例查看不同的行为:

In [1]: d = {'P1000': 361, 'P200': 361, 'P3': 391, 'P6': 361, 'P4': 361, 'P5': 361,"P100":361}

In [2]: import re

In [3]: patt =  re.compile("[^\d]")

In [4]: def cmp(x):
   ...:         return patt.search(x).group(), int(patt1.search(x).group())
   ...: print(sorted(d.items(), key=lambda x: (-x[1], cmp(x[0]))))
   ...: print(sorted(d.items(), key=lambda x: (-x[1], x[0])))
   ...: 
[('P3', 391), ('P4', 361), ('P5', 361), ('P6', 361), ('P100', 361), ('P200', 361), ('P1000', 361)]
[('P3', 391), ('P100', 361), ('P1000', 361), ('P200', 361), ('P4', 361), ('P5', 361), ('P6', 361)]
假设字符始终为字母的正则表达式的替代方案:

from itertools import  takewhile

def cmp(x):
    take = "".join(takewhile(str.isalpha, x))
    return take, int(x[len(take):])
print(sorted(d.items(), key=lambda x: (-x[1], (cmp(x[0])))))
如果它始终是1个字母,然后是n个数字,则可以简化为:

sorted(d.items(), key=lambda x: (-x[1], (x[0][0], int(x[0][1:])))

你认为降序是什么?是
“P100”
“P2”
还是
@PadraicCunningham的键“P2”>“P1”我要求的是
“P100”与“P2”
,因为使用字典排序可以认为P2更大,如果你不想这样,那么会有更多的涉及,是的,“P100”>“P2”不用担心,人们经常会被抓住,这就是我问的原因。