内置容器的自定义比较

2023-12-31

在我的代码中,对各种容器(列表、字典等)的相等性进行了大量比较。容器的键和值的类型为 float、bool、int 和 str。内置的 == 和 != 工作得很好。

我刚刚了解到,必须使用自定义比较函数来比较容器值中使用的浮点数。我已经编写了该函数(我们将其称为 approxEqual(),并假设它需要两个浮点数,如果判断它们相等则返回 True,否则返回 False)。

我希望将对现有代码的更改保持在最低限度。 (新的类/函数/等可以根据需要变得复杂。)

Example:

if dict1 != dict2:
  raise DataMismatch

The dict1 != dict2需要重写条件,以便使用 approxEqual 函数而不是比较 dict1 和 dict2 值中使用的任何浮点数__eq__.

字典的实际内容来自各种来源(解析文件、计算等)。

Note: I 之前问过一个问题 https://stackoverflow.com/q/3854047/336527关于如何覆盖内置浮动eq。这本来是一个简单的解决方案,但我了解到 Python 不允许覆盖内置类型”__eq__操作员。因此出现了这个新问题。


改变内置容器检查相等性的方式的唯一途径是使它们包含为值,而不是“原始值”,wrapped值(包装在覆盖的类中__eq__ and __ne__)。如果您需要改变容器本身使用相等性检查的方式,例如为了目的in右侧操作数是列表的运算符——以及容器的方法,例如它们自己的方法__eq__ (type(x).__eq__(y)是 Python 在内部执行代码的典型方式x == y).

如果你说的是表演your own平等检查(without改变容器本身内部执行的检查),那么唯一的方法就是改变每个cont1 == cont2进入(例如)same(cont1, cont2, value_same) where value_same是一个接受两个值并返回的函数True or False like ==会。根据您指定的标准,这可能过于侵入性 WRT。

如果你能改变容器本身(即,创建容器对象的位置数量远小于检查两个容器是否相等的位置数量),然后使用覆盖的容器子类__eq__是最好的。

E.g.:

class EqMixin(object):
  def __eq__(self, other):
    return same(cont1, cont2, value_same)

(with same正如我在 A 的第二段中提到的)

class EqM_list(EqMixin, list): pass

(对于您需要的其他容器类型,依此类推),然后无论您有什么地方(例如)

x = list(someiter)

将其更改为

x = EqM_list(someiter)

并且一定要掌握其他创建列表对象的方法,例如代替

x = [bah*2 for bah in buh]

with

x = EqM_list(bah*2 for bah in buh)

and

x = d.keys()

with

x = EqM_list(d.iterkeys())

等等。

是的,我知道,这很麻烦——但这是 Python 的核心原则(和实践;-),内置类型(无论是容器,还是值类型,例如float) 他们自己cannot被改变。这是一种与例如非常不同的哲学。 Ruby 和 Javascript(我个人更喜欢它,但我确实看到它有时看起来有限制!)。

Edit:OP的具体要求似乎是(就这个答案而言)“我如何实现same”对于各种容器类型,不在于如何在不改变容器的情况下应用它==进入函数调用。如果这是正确的,那么(例如)为了简单起见,不使用迭代器:

def samelist(a, b, samevalue):
    if len(a) != len(b): return False
    return all(samevalue(x, y) for x, y in zip(a, b))

def samedict(a, b, samevalue):
    if set(a) != set(b): return False
    return all(samevalue(a[x], b[x]) for x in a))

请注意,这适用于values, 按照要求,NOT to keys。 “模糊”字典的键(或集合的成员)的相等比较是REAL问题。这样看:首先,你如何绝对确定的保证 that samevalue(a, b) and samevalue(b, c)完全暗示并确保samevalue(a, c)?这种传递性条件不适用于我见过的大多数半明智的“模糊比较”,但对于基于哈希表的容器(例如字典和集合)来说它是完全不可或缺的。如果你克服了这个障碍,那么让散列值以某种方式“神奇地”一致的噩梦就会出现——如果一个字典中的两个实际上不同的键在这种意义上“映射到”相等性,会怎么样?the samekey 在另一个字典中,那么应该使用两个相应值中的哪一个......?这就是疯狂所在,如果你问我,所以我希望当你说values you do确切地说,意思是values, and not keys!-)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

内置容器的自定义比较 的相关文章

随机推荐