在我的代码中,对各种容器(列表,字典等)的相等性进行了大量的比较.容器的键和值的类型为float,bool,int和str.内置的==和!=工作得非常好.
我刚刚了解到必须使用自定义比较函数来比较容器值中使用的浮点数.我已经编写了这个函数(让我们称它为approxEqual(),并假设它需要两个浮点数,如果它们被判断为相等则返回True,否则返回False).
我更喜欢将现有代码的更改保持在最低限度.(新的类/函数/等可以根据需要复杂化.)
例:
if dict1 != dict2:
raise DataMismatch
Run Code Online (Sandbox Code Playgroud)
的dict1 != dict2条件需要使得在dict1和dict2的值中所使用的任何浮子正在使用approxEqual比较功能,而不是重写__eq__.
字典的实际内容来自各种来源(解析文件,计算等).
注意:我之前问了一个关于如何覆盖内置float的eq的问题.这本来是一个简单的解决方案,但我了解到Python不允许覆盖内置类型的__eq__运算符.因此这个新问题.
要改变内置容器检查的平等是让他们作为包含值的方式的唯一途径,而不是"原件",包裹值(包裹在覆盖类__eq__和__ne__).这是你需要改变容器本身使用等式检查的方式,例如,为了in操作员的目的,右边操作数是一个列表 - 以及容器的方法,如他们自己__eq__(type(x).__eq__(y)是典型的) Python将在内部执行代码编写的方式x == y.
如果您正在谈论的是执行您自己的相等检查(不改变容器本身在内部执行的检查),那么唯一的方法是将每个更改cont1 == cont2为(例如)same(cont1, cont2, value_same)where value_same一个函数接受两个值并返回True或False类似==将.这可能是太具侵略性的WRT你指定的标准.
如果您可以自己更改容器(即,创建容器对象的位置数远远小于检查两个容器是否相等的位置数),那么使用覆盖的容器子类__eq__是最好的.
例如:
class EqMixin(object):
def __eq__(self, other):
return same(cont1, cont2, value_same)
Run Code Online (Sandbox Code Playgroud)
(same正如我在A的第2段中提到的那样)和
class EqM_list(EqMixin, list): pass
Run Code Online (Sandbox Code Playgroud)
(等等您需要的其他容器类型),然后在任何地方(例如)
x = list(someiter)
Run Code Online (Sandbox Code Playgroud)
改成它
x = EqM_list(someiter)
Run Code Online (Sandbox Code Playgroud)
并确保还捕获其他方法来创建列表对象,例如替换
x = [bah*2 for bah in buh]
Run Code Online (Sandbox Code Playgroud)
同
x = EqM_list(bah*2 for bah in buh)
Run Code Online (Sandbox Code Playgroud)
和
x = d.keys()
Run Code Online (Sandbox Code Playgroud)
同
x = EqM_list(d.iterkeys())
Run Code Online (Sandbox Code Playgroud)
等等.
是的,我知道,这是多么麻烦 - 但它是Python的核心原则(和实践;-)内置类型(无论是容器,还是类似的值类型float)本身都无法改变.这是一个非常不同的哲学,例如Ruby和Javascript(我个人更喜欢它,但我确实看到它有时看起来有限!).
编辑: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))
Run Code Online (Sandbox Code Playgroud)
请注意,这适用于请求的值,而不适用于键."模糊"dict键(或一组成员)的平等比较是一个真正的问题.看它是这样的:第一,怎么给你保证绝对肯定的是samevalue(a, b) and samevalue(b, c)完全暗示,并保证samevalue(a, c)?这种传递性条件不适用于我见过的大多数半合理的"模糊比较",但它对于基于散列表的容器(例如dicts和sets)来说是完全不可或缺的.如果你通过了这个障碍,那么就会出现使哈希值以某种方式"神奇地"保持一致的噩梦 - 如果一个词典中的两个实际上不同的键"映射到"会怎么样?在其他字典中键入,那么应该使用两个相应值中的哪一个......?这样疯狂的谎言,如果你问我,所以我希望,当你说值,你做的确切含义是,价值观,并没有钥匙- !)
| 归档时间: |
|
| 查看次数: |
2457 次 |
| 最近记录: |