微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

__eq__() 在嵌套数据结构中多次调用而不是一次

如何解决__eq__() 在嵌套数据结构中多次调用而不是一次

一年一两次,我遇到以下问题:我有一些比较操作可能很昂贵的类型(例如,值太大而无法保存在内存中,需要从磁盘加载或相等性很难计算,因为单个值可能有很多表示,想想化学公式)。这种类型是嵌套数据结构的一部分(例如嵌套列表或元组或某些树)。有时,我注意到我的类型上的比较运算符(__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 举报,一经查实,本站将立刻删除。