python中特殊向量之间的关系

python中特殊向量之间的关系,python,python-3.x,function,vector,relation,Python,Python 3.x,Function,Vector,Relation,我想知道是否有办法在一些特殊的“向量”之间建立关系 例如: 假设这些是我的向量(我只选择3个特殊向量): 我想在比较它们时添加以下规则(字典顺序): 我想说 a<b a您可以很容易地编写一个函数来执行所描述的操作 def special_lt(vec1, vec2): 您已经将“正常”值定义为除最后一个以外的所有值,“特殊”值定义为最后一个值,因此这很简单: normal1, normal2 = vec1[:-1], vec2[:-1] special1, sp

我想知道是否有办法在一些特殊的“向量”之间建立关系

例如:

假设这些是我的向量(我只选择3个特殊向量):

我想在比较它们时添加以下规则(字典顺序):

我想说

   a<b 

a您可以很容易地编写一个函数来执行所描述的操作

def special_lt(vec1, vec2):
您已经将“正常”值定义为除最后一个以外的所有值,“特殊”值定义为最后一个值,因此这很简单:

    normal1, normal2 = vec1[:-1], vec2[:-1]
    special1, special2 = vec1[-1], vec2[-1]
现在,如果我理解正确,你想对正常值做一个字典比较,然后根据特殊值,如果它们相等

    if normal1 == normal2:
        return special1 < special2
如果normal1==normal2:
返回special1
…但在其他情况下,使用特殊值作为检查,以确保其顺序与正常值相同:

    elif normal1 < normal2:
        if special1 <= special2:
            return True
        raise ValueError('not comparable')
    else:
        if special2 <= special1:
            return False
        raise ValueError('not comparable')
elif normal1如果特别1您可以很容易地编写一个函数来执行所描述的操作

def special_lt(vec1, vec2):
您已经将“正常”值定义为除最后一个以外的所有值,“特殊”值定义为最后一个值,因此这很简单:

    normal1, normal2 = vec1[:-1], vec2[:-1]
    special1, special2 = vec1[-1], vec2[-1]
现在,如果我理解正确,你想对正常值做一个字典比较,然后根据特殊值,如果它们相等

    if normal1 == normal2:
        return special1 < special2
如果normal1==normal2:
返回special1
…但在其他情况下,使用特殊值作为检查,以确保其顺序与正常值相同:

    elif normal1 < normal2:
        if special1 <= special2:
            return True
        raise ValueError('not comparable')
    else:
        if special2 <= special1:
            return False
        raise ValueError('not comparable')
elif normal1如果是special1,您可以将
vector
作为
列表的子类,并重载
\uUlt\uU
\uUgt\uU
方法,以便在默认行为之前检查最后一项。此外,还要重载
\uuuuuuuuuuuuuuuu
\uuuuuuuuu
方法以确保完整性:

class vector(list):
    def __lt__(self, other):
        lt = super().__lt__(other)
        if lt and self[-1] > other[-1]:
            return False
        return lt
    def __gt__(self, other):
        gt = super().__gt__(other)
        if gt and self[-1] < other[-1]:
            return False
        return gt
    def __le__(self, other):
        if self == other:
            return True
        return self < other
    def __ge__(self, other):
        if self == other:
            return True
        return self > other
编辑:根据下面的评论,我还想指出,
functools.total_排序
不起作用,因为OP需要非典型逻辑,其中一个对象可以同时不小于、不大于和不等于另一个对象

因此,如果我们只为
vector
类定义
\uuu lt\uuu
方法,并应用
总排序
装饰器:

from functools import total_ordering
@total_ordering
class vector(list):
    def __lt__(self, other):
        lt = super().__lt__(other)
        if lt and self[-1] > other[-1]:
            return False
        return lt
上述测试代码将产生以下不正确的输出:

True
True
False
False
False
True
True
False

您可以将
vector
设置为
list
的子类,并重载
\uult\uuuu
\ugt\uuu
方法,以便在默认行为之前检查最后一项。此外,还要重载
\uuuuuuuuuuuuuuuu
\uuuuuuuuu
方法以确保完整性:

class vector(list):
    def __lt__(self, other):
        lt = super().__lt__(other)
        if lt and self[-1] > other[-1]:
            return False
        return lt
    def __gt__(self, other):
        gt = super().__gt__(other)
        if gt and self[-1] < other[-1]:
            return False
        return gt
    def __le__(self, other):
        if self == other:
            return True
        return self < other
    def __ge__(self, other):
        if self == other:
            return True
        return self > other
编辑:根据下面的评论,我还想指出,
functools.total_排序
不起作用,因为OP需要非典型逻辑,其中一个对象可以同时不小于、不大于和不等于另一个对象

因此,如果我们只为
vector
类定义
\uuu lt\uuu
方法,并应用
总排序
装饰器:

from functools import total_ordering
@total_ordering
class vector(list):
    def __lt__(self, other):
        lt = super().__lt__(other)
        if lt and self[-1] > other[-1]:
            return False
        return lt
上述测试代码将产生以下不正确的输出:

True
True
False
False
False
True
True
False


您是否需要将第三个值包含在它自己的单个项目列表中?这样您的空间中的某些向量就可能不可比较了?听起来很奇怪。无法保证在空间中的向量上定义的集合是可排序的。因此,是否希望
b
c
都为false?您可能希望定义一个类,该类可以覆盖
\uuult\uuuu
等来表示向量,而不仅仅是隐式使用列表。是的,b和c不可比较,因此bDo您需要在其自己的单个项目列表中包含第三个值?因此您的空间中可能有两个向量不可比较?听起来很奇怪。无法保证在空间中的向量上定义的集合是可排序的。因此,是否希望
b
c
都为false?您可能希望定义一个类,该类可以覆盖
\u lt\u
等来表示向量,而不仅仅是隐式使用列表。是的,b和c是不可比较的,所以最好只定义
\u lt\u
(和
\u eq\u
,如果需要),然后使用
@functools.total\u ordering
。那么你不必重复逻辑四次。(有时出于性能原因,您不得不重复它们,但在这种情况下,对于非平凡的类,我通常仍然编写代码来生成方法,只是在类定义时,而不是在运行中。)不,
@functools.total_ordering
不是魔术
@functools.total\u ordering
依赖于对象之间的逻辑关系,因此如果我只定义
\u lt\u
,那么
\u gt\u
的返回值始终是
\u lt\u
的否定,而在OP的情况下不是。
total\u ordering
取决于您给出的值,但
\u gt__(self,other)
不是
not\uu lt\uuuu(self,other)
,它是
\uu lt\uuuuu(other,self)
。更一般地说,它适用于总排序和偏序,其中所有内容要么与总排序相同,要么是例外;它不一定适用于奇怪的NaN样式的排序。如果OP希望这样,那么是的,您可能无法使用它。因为所需的逻辑与直观的
总排序相反de>,我建议将这个“特殊排序”作为一个单独的类混合到一个普通的
向量
类中。参考@pylang了解它的价值,编写一个
@weird\u排序
装饰器非常简单(我在GitHub的某个地方有一个
@nanu排序
)-但是,除非你计划使用多个这样的类型,或者你可以想出一个名称,使规则的含义比代码更清晰,否则我不会为抽象而烦恼;我只会像blhsing那样手工编写。更好