问题描述
一年一两次,我遇到以下问题:我有一些比较操作可能很昂贵的类型(例如,值太大而无法保存在内存中,需要从磁盘加载或相等性很难计算,因为单个值可能有很多表示,想想化学公式)。这种类型是嵌套数据结构的一部分(例如嵌套列表或元组或某些树)。有时,我注意到我的类型上的比较运算符(__lt__
等)在一次比较中被多次调用以获取相同的值。
我会试着用下面的例子来说明这个问题:
class X:
comparisons = 0
def __init__(self,value):
self.value = value
def __lt__(self,other):
return self.value < other.value
def __gt__(self,other):
return self.value > other.value
def __eq__(self,other):
X.comparisons += 1
return self.value == other.value
def nest_a_hundred_times(value):
for i in range(100): value = [value]
return value
print(nest_a_hundred_times(X(1)) < nest_a_hundred_times(X(0)))
print(X.comparisons)
在此示例中,X
是我的类型,具有昂贵的比较操作,我只是计算调用 __eq__()
的次数,但其他操作也可能很昂贵。该类型的两个不相等的值被创建并嵌套在单元素列表中。
运行示例打印 False
,100
。所以 __eq__()
被调用了 100 次。
我知道为什么会发生这种情况:the built-in comparison function for list
objects 首先比较各个列表元素的相等性,以找出两个列表在哪个索引处不同,然后再比较这些元素进行排序。我认为仅使用六个比较运算符(==
、!=
、<
、<=
、>
、{{ 1}}) 作为定义排序的类型之间的接口。作为替代方法的示例,Haskell 有一个 Ord
类,它定义了一个 >=
函数来比较两个值。这允许通过在每个节点上仅调用一次 ordering
来比较嵌套数据结构。
我的问题是:如何在 Python 中避免这个问题?与我的信念相反,是否有可能避免仅由 Python 定义的比较运算符的问题? (我试图避免某种结果缓存,因为这不是性能问题,而是算法问题)。或者我是否需要构建自己的数据结构(列表、元组)并在其上实现 ordering
函数?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)