python 中特殊向量之间的关系
Relations between special vectors in python
我想知道是否有办法在一些特殊的 "vectors" 之间建立关系。
示例:
假设这些是我的向量(我只会选择 3 个特殊向量):
a=[1,2,[1]]
b=[1,2,[2]]
c=[1,3,[1]]
并且我想在比较它们时添加以下规则(字典顺序):
我想说
a<b
因为
a[0]=b[0] and a[1]=b[1] but *a[2]<b[2]*
但我也想说
a<c
因为
a[0]=b[0] and a[1]<c[1] and a[2]<=c[2]
但请注意,"b" 和 "c" 的情况略有不同,因为它们不可比较,因为即使
b[0]=c[0] and b[1]<c[1], the last term changes everything since b[2]>c[2]
换句话说,我正在应用的规则将首先比较两个向量 x 和 y 的 "normal" 个条目,如果向量 x 的某个条目大于向量 y 的某个条目,我们看看最后一个条目。如果向量x的最后一项大于或等于,那么我们说x>y,如果不是这样,那么x和y不可比。
如果 x 和 y 的所有 "normal" 条目都相同,我们比较最后一个条目。如果 x 的最后一个条目大于 y 的最后一个条目,我们也说 x>y。
我认为这与 while 循环有关。
您可以轻松编写一个函数来执行您描述的操作。
def special_lt(vec1, vec2):
您已将 "normal" 值定义为除最后一个以外的所有值,并将 "special" 值定义为最后一个,所以这很简单:
normal1, normal2 = vec1[:-1], vec2[:-1]
special1, special2 = vec1[-1], vec2[-1]
现在,如果我没理解错的话,你想对正常值进行字典顺序比较,然后在它们相等时遵从特殊值...
if normal1 == normal2:
return special1 < special2
… 但除此之外,使用特殊值作为检查以确保它们的排序方式与正常值相同:
elif normal1 < normal2:
if special1 <= special2:
return True
raise ValueError('not comparable')
else:
if special2 <= special1:
return False
raise ValueError('not comparable')
请注意,为了比较正常值列表和特殊值列表,我没有使用循环;我只是比较了列表。那是因为列表已经按字典顺序进行了比较(当然,在内部,这是通过循环完成的,但我不必编写它)。
您可以使 vector
成为 list
的子 class 并重载 __lt__
和 __gt__
方法,以便在默认行为。还要重载 __le__
和 __ge__
方法以确保完整性:
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
这样:
a=vector([1,2,[1]])
b=vector([1,2,[2]])
c=vector([1,3,[1]])
print(a<b)
print(a<c)
print(b<c)
print(c<b)
print(b>c)
print(c>b)
print(b<=c)
print(c<=b)
将输出:
True
True
False
False
False
False
False
False
编辑:鉴于下面的评论,我还想指出,在这种情况下 functools.total_ordering
不起作用,因为非典型OP 要求的逻辑,其中一个对象可以同时不小于、不大于和不等于另一个对象。
因此,如果我们只为 vector
class 定义 __lt__
方法并应用 total_ordering
装饰器:
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
我想知道是否有办法在一些特殊的 "vectors" 之间建立关系。
示例:
假设这些是我的向量(我只会选择 3 个特殊向量):
a=[1,2,[1]]
b=[1,2,[2]]
c=[1,3,[1]]
并且我想在比较它们时添加以下规则(字典顺序):
我想说
a<b
因为
a[0]=b[0] and a[1]=b[1] but *a[2]<b[2]*
但我也想说
a<c
因为
a[0]=b[0] and a[1]<c[1] and a[2]<=c[2]
但请注意,"b" 和 "c" 的情况略有不同,因为它们不可比较,因为即使
b[0]=c[0] and b[1]<c[1], the last term changes everything since b[2]>c[2]
换句话说,我正在应用的规则将首先比较两个向量 x 和 y 的 "normal" 个条目,如果向量 x 的某个条目大于向量 y 的某个条目,我们看看最后一个条目。如果向量x的最后一项大于或等于,那么我们说x>y,如果不是这样,那么x和y不可比。
如果 x 和 y 的所有 "normal" 条目都相同,我们比较最后一个条目。如果 x 的最后一个条目大于 y 的最后一个条目,我们也说 x>y。
我认为这与 while 循环有关。
您可以轻松编写一个函数来执行您描述的操作。
def special_lt(vec1, vec2):
您已将 "normal" 值定义为除最后一个以外的所有值,并将 "special" 值定义为最后一个,所以这很简单:
normal1, normal2 = vec1[:-1], vec2[:-1]
special1, special2 = vec1[-1], vec2[-1]
现在,如果我没理解错的话,你想对正常值进行字典顺序比较,然后在它们相等时遵从特殊值...
if normal1 == normal2:
return special1 < special2
… 但除此之外,使用特殊值作为检查以确保它们的排序方式与正常值相同:
elif normal1 < normal2:
if special1 <= special2:
return True
raise ValueError('not comparable')
else:
if special2 <= special1:
return False
raise ValueError('not comparable')
请注意,为了比较正常值列表和特殊值列表,我没有使用循环;我只是比较了列表。那是因为列表已经按字典顺序进行了比较(当然,在内部,这是通过循环完成的,但我不必编写它)。
您可以使 vector
成为 list
的子 class 并重载 __lt__
和 __gt__
方法,以便在默认行为。还要重载 __le__
和 __ge__
方法以确保完整性:
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
这样:
a=vector([1,2,[1]])
b=vector([1,2,[2]])
c=vector([1,3,[1]])
print(a<b)
print(a<c)
print(b<c)
print(c<b)
print(b>c)
print(c>b)
print(b<=c)
print(c<=b)
将输出:
True
True
False
False
False
False
False
False
编辑:鉴于下面的评论,我还想指出,在这种情况下 functools.total_ordering
不起作用,因为非典型OP 要求的逻辑,其中一个对象可以同时不小于、不大于和不等于另一个对象。
因此,如果我们只为 vector
class 定义 __lt__
方法并应用 total_ordering
装饰器:
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