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”不用担心,人们经常会被抓住,这就是我问的原因。