50

所以我正在使用一些预先存在的比较器来比较两个元组中的某些值,如果第一个大于第二个,则返回 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)。我无法更改比较器功能。

4

4 回答 4

55

您将比较器作为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实际上不是 a dict,因此名称相当混乱。)

于 2012-10-05T15:31:42.157 回答
46

在 Python 3 中,函数没有cmp参数sorted(也没有 for list.sort)。

根据文档,签名现在是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函数协议,因为它返回Trueor 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中的函数。

于 2020-02-10T21:56:24.950 回答
1

@kaya3的答案是正确的。我只是提出另一种实现,我们可以在其中使用布尔值作为比较器。

class YourTupleComparator(tuple):
    def __lt__(self, other):
        return self[0] < other[0]

sorted(subjects, key=YourTupleComparator)
于 2021-11-23T00:39:57.070 回答
-1

我们现在可以使用它对二维数组进行排序:

A.sort(key=lambda a: (a[0], -a[1]))

这将按 A[0] 的升序和 A[1] 的降序对二维数组进行排序。

于 2022-02-20T12:02:24.137 回答