所以我正在使用一些预先存在的比较器,它们比较两个元组中的某些值,如果第一个元组大于第二个元组,则返回 true,否则返回 false。以下是其中之一的代码:
def cmpValue(subInfo1, subInfo2):
"""
Returns True if value in (value, work) tuple subInfo1 is GREATER than
value in (value, work) tuple in subInfo2
"""
# TODO...
if subInfo1[0] > subInfo2[0]:
return True
else:
return False
现在,我有一个字典,其中包含许多上面比较的元组条目。我想以相反的顺序对它们进行排序,但我真的不明白我将如何做到这一点。我在想这样的事情:
sortedDict = sorted(subjects, key=comparator, reverse = True)
但我不知道该将什么传递到比较器中,因为每个比较器都接受两个参数(subInfo1,subInfo2)。我无法更改比较器功能。
在 Python 3 中,sorted
函数(list.sort
也没有cmp
参数)。
根据文档,签名现在sorted(iterable, *, key=None, reverse=False)
,因此您必须使用key
函数进行自定义排序。文档建议:
使用
functools.cmp_to_key()
将旧式 cmp 函数转换为键函数。
下面是一个示例:
>>> def compare(x, y):
... return x[0] - y[0]
...
>>> data = [(4, None), (3, None), (2, None), (1, None)]
>>> from functools import cmp_to_key
>>> sorted(data, key=cmp_to_key(compare))
[(1, None), (2, None), (3, None), (4, None)]
但是,您的函数也不符合旧的cmp
函数协议,因为它返回True
或False
。针对您的具体情况,您可以执行以下操作:
>>> your_key = cmp_to_key(make_comparator(cmpValue))
>>> sorted(data, key=your_key)
[(1, None), (2, None), (3, None), (4, None)]
使用@Fred Foo答案中的make_comparator
函数。
您将比较器作为key
函数传递。你应该把它作为cmp
传递,包装在某种函数中,把它变成一个合适的比较器。
def make_comparator(less_than):
def compare(x, y):
if less_than(x, y):
return -1
elif less_than(y, x):
return 1
else:
return 0
return compare
sortedDict = sorted(subjects, cmp=make_comparator(cmpValue), reverse=True)
(尽管实际上,您应该使用关键功能:
sorted(subjects, operator.itemgetter(0), reverse=True)
另请注意,sortedDict
实际上不会是一个dict
,所以这个名字相当混乱。
@kaya3的答案是正确的。我只是提出了另一种实现,我们可以在其中使用布尔值作为比较器。
class YourTupleComparator(tuple):
def __lt__(self, other):
return self[0] < other[0]
sorted(subjects, key=YourTupleComparator)
周@Tuan的答案是如何工作的。但是,在复杂情况下可能会失败。
考虑这个比较:每个元素都是一个具有二维的元组。如果满足以下两个条件之一,则元素 A
小于 B
:1. A[0]
小于 B[0]
。2. A[0]==B[0]
和A[1]>B[0]
。因此(1, 2) < (2, 1)
,(1, 2) < (1, 1)
。
请尝试以下代码片段:
from functools import cmp_to_key
class Character(tuple):
def __le__(self, other) -> bool:
if self[0] < other[0] or (self[0] == other[0] and self[1] >= other[1]):
return True
return False
def compare(x, y):
if x[0] == y[0]:
return y[1] - x[1]
return x[0] - y[0]
if __name__ == "__main__":
array = [[1, 1], [2, 1], [2, 2], [1, 2]]
print(sorted(array, key=Character)) # [[1, 1], [1, 2], [2, 1], [2, 2]]
print(sorted(array, key=cmp_to_key(compare))) # [[1, 2], [1, 1], [2, 2], [2, 1]]
如您所见,class Character
的结果是错误的。
我们现在可以使用它来对二维数组进行排序:
A.sort(key=lambda a: (a[0], -a[1]))
这将按 A[0] 的升序和 A[1] 的降序对 2d 数组进行排序。