如何在Python3中编写自定义比较器和自定义排序以在sorted()函数中使用。

huangapple go评论76阅读模式
英文:

How to write a custom comparator with custom sort in Python3 to use it in sorted() function

问题

I can provide the translation of the code and the relevant information:

我目前被困在编写比较器的问题上基本思路是编写一个函数它接受两个参数两个列表),但我想将它用于一个包含这些列表的列表以便在sorted()函数中使用它我该如何做

比较器
```python
def dispersion_sort(frec, srec):

    if isinstance(frec, intervals.Interval) and isinstance(srec, intervals.Interval):
        if frec[DOUBLE_RES_COL] < srec[DOUBLE_RES_COL]:
            return frec
        if frec[DOUBLE_RES_COL] > srec[DOUBLE_RES_COL]:
            return srec
        if frec[DOUBLE_RES_COL].overlaps(srec[DOUBLE_RES_COL]):
            if (frec[DOUBLE_TIME_COL] < srec[DOUBLE_TIME_COL]):
                return frec
            else:
                return srec

    return frec

示例 frec 数据:
['1', 'Mikhail Nitenko', '@login', '✅', [-0.000509228437634554,0.0007110924383354339], datetime.datetime(2020, 1, 2, 14, 46, 46)]

我希望如何调用它:

results = sorted(results, key=dispersion_sort)

非常感谢!


<details>
<summary>英文:</summary>

I&#39;m currently stuck on a problem to write a comparator. The base idea was to write a function, which takes to parameters (two lists), but I want to use it on a list of these lists to use it in sorted() function. How shall I do it?

Comparator:
```python
def dispersion_sort(frec, srec):

    if isinstance(frec, intervals.Interval) and isinstance(srec, intervals.Interval):
        if frec[DOUBLE_RES_COL] &lt; srec[DOUBLE_RES_COL]:
            return frec
        if frec[DOUBLE_RES_COL] &gt; srec[DOUBLE_RES_COL]:
            return srec
        if frec[DOUBLE_RES_COL].overlaps(srec[DOUBLE_RES_COL]):
            if (frec[DOUBLE_TIME_COL] &lt; srec[DOUBLE_TIME_COL]):
                return frec
            else:
                return srec

    return frec

Sample frec data:
[&#39;1&#39;, &#39;Mikhail Nitenko&#39;, &#39;@login&#39;, &#39;✅&#39;, [-0.000509228437634554,0.0007110924383354339], datetime.datetime(2020, 1, 2, 14, 46, 46)]

How I wanted to call it:

results = sorted(results, key=dispersion_sort)

Thanks a lot!

答案1

得分: 1

你可以使用 functools.cmp_to_key 来实现这个:

from functools import cmp_to_key

results = sorted(results, key=cmp_to_key(dispersion_sort))

它会将旧式的比较函数(接受两个参数)转换为新式的键函数(接受一个参数)。

英文:

You can use functools.cmp_to_key for this:

from functools import cmp_to_key

results = sorted(results, key=cmp_to_key(dispersion_sort))

It will transform the old style comparator function (which takes two arguments), into a new style key function (which takes one argument).

答案2

得分: 0

Here is the translated code part:

如果你想显式创建一个比较器你需要实现一个自定义类该类具有以下魔术方法
```python
class comparator:
        def __init__(self, obj, *args):
            self.obj = obj
        def __lt__(self, other):
            return mycmp(self.obj, other.obj) < 0
        def __gt__(self, other):
            return mycmp(self.obj, other.obj) > 0
        def __eq__(self, other):
            return mycmp(self.obj, other.obj) == 0
        def __le__(self, other):
            return mycmp(self.obj, other.obj) <= 0
        def __ge__(self, other):
            return mycmp(self.obj, other.obj) >= 0
        def __ne__(self, other):
            return mycmp(self.obj, other.obj) != 0

在这里,函数 mycmp 就像你展示的那样。你也可以选择将你的逻辑直接放入类中。在这里,这些方法应该返回 TrueFalse,这与你当前的函数不同。如果你想直接将当前的函数用于这个类模板,确保相应地进行更改。

一旦你准备好了这个类,你可以直接传递它:key=comparator


<details>
<summary>英文:</summary>

If you wanted to explicitly create a comparator, you&#39;d want to implement a custom class that has that has these magic methods:
```python
class comparator:
        def __init__(self, obj, *args):
            self.obj = obj
        def __lt__(self, other):
            return mycmp(self.obj, other.obj) &lt; 0
        def __gt__(self, other):
            return mycmp(self.obj, other.obj) &gt; 0
        def __eq__(self, other):
            return mycmp(self.obj, other.obj) == 0
        def __le__(self, other):
            return mycmp(self.obj, other.obj) &lt;= 0
        def __ge__(self, other):
            return mycmp(self.obj, other.obj) &gt;= 0
        def __ne__(self, other):
            return mycmp(self.obj, other.obj) != 0

Here, the function mycmp is a function like the one you showed. You can also choose to put your logic directly in the class itself. Here, these methods should return a True or False, which is different from your current function. Make sure that is changed accordingly if you want to use the current function directly into this class template.

Once you have the class ready , you can pass it in directly: key=comparator

huangapple
  • 本文由 发表于 2020年1月3日 23:34:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/59581285.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定