gpt4 book ai didi

python - 内置容器的自定义比较

转载 作者:太空狗 更新时间:2023-10-30 00:46:52 34 4
gpt4 key购买 nike

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

我刚刚了解到容器值中使用的 float 必须使用自定义比较函数进行比较。我已经编写了那个函数(我们称它为 approxEqual(),并假设它接受两个 float ,如果判断它们相等则返回 True,否则返回 False)。

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

例子:

if dict1 != dict2:
raise DataMismatch

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

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

注:我asked a question earlier关于如何覆盖内置 float 的 eq。这本来是一个简单的解决方案,但我了解到 Python 不允许覆盖内置类型的 __eq__ 运算符。因此提出了这个新问题。

最佳答案

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

如果您所说的是执行您自己的相等性检查(没有改变容器本身在内部执行的检查),那么唯一的方法就是改变每个 cont1 == cont2 到(例如)same(cont1, cont2, value_same) 其中 value_same 是一个接受两个值并返回 TrueFalse 就像 == 一样。根据您指定的标准,这可能过于具有侵入性。

如果您可以更改容器本身(即,创建容器对象的地方的数量远小于检查两个容器是否相等的地方的数量),那么使用容器覆盖 __eq__ 的子类是最好的。

例如:

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

(相同如我在 A 的第 2 段中提到的那样)和

class EqM_list(EqMixin, list): pass

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

x = list(someiter)

改成

x = EqM_list(someiter)

并且一定要捕获其他方式来创建列表对象,例如替换

x = [bah*2 for bah in buh]

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

x = d.keys()

x = EqM_list(d.iterkeys())

等等。

是的,我知道,这很麻烦——但它是 Python 的核心原则(和实践;-),内置类型(无论是容器,还是值类型,例如 float)本身 < strong>不能改变。这是一个非常不同的哲学。 Ruby 和 Javascript(我个人更喜欢它,但我确实看到它有时看起来有局限性!)。

编辑:OP 特定要求似乎是(就此答案而言)“我如何为各种容器类型实现相同”,而不是如何应用它没有将 == 更改为函数调用。如果那是正确的,那么(例如)为了简单起见不使用迭代器:

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))

请注意,根据要求,这适用于不适用于。 “模糊化”字典键(或集合成员)的相等性比较是一个真实问题。这样看:首先,您如何绝对确定 samevalue(a, b) 和 samevalue(b, c) 完全暗示并确保 相同值(a,c)?这种传递性条件不适用于我见过的大多数半明智的“模糊比较”,但它对于基于哈希表的容器(如字典和集合)来说是完全不可或缺的。如果你通过了这个障碍,那么使散列值以某种方式“神奇地”保持一致的噩梦就会出现——如果一个字典中的两个实际上不同的键在这个意义上“映射到”相等性与相同另一个字典中的键,那么应该使用两个对应值中的哪一个......?如果你问我,疯狂就是这样撒谎的,所以我希望当你说值(value)观时,你确实的意思是值(value)观,并且不是键!-)

关于python - 内置容器的自定义比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3860009/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com