gpt4 book ai didi

Python:使用 __cmp__ 对间隔进行排序,其中 __lt__ 表示 "strictly less than"

转载 作者:行者123 更新时间:2023-11-30 23:17:11 25 4
gpt4 key购买 nike

我有一个intervaltree需要对Intervals进行排序并最终对Points进行排序的库。

我有一个 __cmp__ 方法,它强制执行非常稳定和逻辑的排序(请参阅代码末尾)。而且,我有一个有用的 __lt__ 方法来查看间隔是否严格小于彼此(同上)。

我对此行为进行了大约 30 次测试,一切进展顺利......

问题

...除非我必须排序:

>>> sorted([Interval(0, 10), Interval(-10, 5)])
[Interval(0, 10), Interval(-10, 5)] # WRONG!

因为Python使用__lt__,所以它使用“严格小于”语义而不是__cmp__。我可以强制它显式地执行此操作,但我宁愿避免使用繁琐的语法:

>>> sorted([Interval(0, 10), Interval(-10, 5)], cmp=Interval.__cmp__)
[Interval(-10, 5), Interval(0, 10)] # RIGHT

在Python 3中,语法更加繁琐(Python 2.6中没有,Python 2.7中可用)。

>>> from functools import cmp_to_key
>>> sorted([Interval(0, 10), Interval(-10, 5)], key=cmp_to_key(Interval.__cmp__))

我想要什么

有没有办法让 sorted() 和 friend 自动使用 Interval.__cmp__ ,但仍然保持 __lt__ 原样?也就是说,我想要这种优雅的行为:

>>> sorted([Interval(0, 10), Interval(-10, 5)])   # no extra arguments!
[Interval(-10, 5), Interval(0, 10)]

附录:__cmp____lt__ 的实现

def __cmp__(self, other):
"""
Tells whether other sorts before, after or equal to this
Interval.

Sorting is by begins, then by ends, then by data fields.

If data fields are not both sortable types, data fields are
compared alphabetically by type name.
:param other: Interval
:return: -1, 0, 1
:rtype: int
"""
s = self[0:2]
try:
o = other[0:2]
except:
o = (other,)
if s != o:
return -1 if s < o else 1
try:
if self.data == other.data:
return 0
return -1 if self.data < other.data else 1
except TypeError:
s = type(self.data).__name__
o = type(other.data).__name__
if s == o:
return 0
return -1 if s < o else 1

def __lt__(self, other):
"""
Less than operator. Returns False if there is an overlap.
:param other: Interval or point
:return: True or False
:rtype: bool
"""
return not self.overlaps(other) and self.end <= other

PS:这个问题出现在开发分支中,我想将 __lt__ 的行为更改为“严格小于”。在 master 分支(版本 1.1.0)中,__lt__ 只是模仿 __cmp__

更新

  • (2014-12-12):现在在我的开发分支中,我提供 Interval.sortedInterval.key。但仍然不是那么优雅。我还在寻找更好的方法!

最佳答案

我强烈建议不要为您的类定义任何订单运算符

原因是顺序运算符的存在意味着存在顺序关系及其关联的语义,而您的类本质上违反了这些语义(间隔上没有明确定义的顺序关系)。

例如,顺序关系意味着:

not(a<b) and not(b<a) ==> a==b

对于间隔来说,情况并非如此。

换句话说,您不应该只决定您希望运算符的含义(例如,__lt__ 表示严格小于),语义是预先定义的适合您的语言(例如 sorted 的实现依赖于该语义)。

您应该做的是定义用于比较的非运算符方法(例如 def strict_lt(self, other): ...),并使用它们。我还定义了一个 sort_intervals 函数,并在代码中使用它,而不是直接使用 sorted 。例如:

def sort_intervals(lst):
return sorted(lst, cmp = ...)

关于Python:使用 __cmp__ 对间隔进行排序,其中 __lt__ 表示 "strictly less than",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27413491/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com