我有两个Python列表。
a = [A(1), B(1)]
b = [A(1), B(2)]
支票a < b
无法调用B的__lt__
运算符。结论是 a 不小于 b 。
我已经验证了A的__lt__
被调用(实际上是两次以查看 a 中的第一个元素是否小于 b 中的元素,然后以另一种方式周围。)
预先感谢
Oren
答案 0 :(得分:2)
在Python中比较两个列表时,它将逐个元素地比较它们,并在找到两个不相等的元素后停止比较它们。这并不意味着一个元素必须大于或小于另一个,而不仅仅是它们不相等。这是一个幼稚的示例,使用了与您所拥有的东西相似的东西;考虑一个class A
:
class A:
def __init__(self, val):
self.val = val
def __lt__(self, obj):
return self.val < obj.val
现在考虑两个对象a
和b
,使得a = A(1)
和b = A(1)
。 a < b
的取值为False
,与我们期望的一样,但是a == b
的取值为False
。这是因为对象无法通过__eq__
方法比较相等性,并且对象不是完全相同的实例。我们可以这样添加一个:
def __eq__(self, obj):
return self.val == obj.val
现在,a == b
的计算结果为True
,您的原始表达式将按预期工作。
答案 1 :(得分:1)
只有在发现第一项相等时,Python才会比较第二项。如果不比较第二个项目,则意味着第一个项目不相等。
因此,问题可能出在A的__lt__
实现上,如果您想发布该代码,我们也许可以帮助发现问题。
答案 2 :(得分:1)
the python documentation明确指出,在第一个不相等的对象上调用了 lt 。在您的示例中,您没有提到您添加了 eq 运算符,所以这是我的复制品:
class A:
def __init__(self, val):
self.val = val
def __lt__(self, other):
print('lt in A')
return self.val < other.val
class B:
def __init__(self, val):
self.val = val
def __lt__(self, other):
print('lt in B')
return self.val < other.val
a = [A(1), B(2)]
b = [A(1), B(1)]
print(a < b)
输出:
lt in A
False
因为第一个对象是不同的(尽管值相同),它将采用该 lt
的结果当您实现__eq__
方法时,它将继续这样做:
A类:
def init (self,val):
self.val = val
def __lt__(self, other):
print('lt in A')
return self.val < other.val
def __eq__(self, other):
return self.val == other.val
将输出
lt in B
True
因为第一个元素使用 eq
评估为true