Python 内置容器的自定义比较
在我的代码中,对各种容器(list、dict等)的相等性进行了大量比较。容器的键和值的类型为float、bool、int和str。内置==和!=工作得非常好 我刚刚了解到,容器值中使用的浮点数必须使用自定义比较函数进行比较。我已经编写了该函数(我们将其称为approxEqual(),并假设它需要两个浮点,如果判断它们相等,则返回True,否则返回False) 我希望对现有代码的更改保持在最低限度。(新类/函数/等可能会根据需要变得复杂。) 例如:Python 内置容器的自定义比较,python,comparison,Python,Comparison,在我的代码中,对各种容器(list、dict等)的相等性进行了大量比较。容器的键和值的类型为float、bool、int和str。内置==和!=工作得非常好 我刚刚了解到,容器值中使用的浮点数必须使用自定义比较函数进行比较。我已经编写了该函数(我们将其称为approxEqual(),并假设它需要两个浮点,如果判断它们相等,则返回True,否则返回False) 我希望对现有代码的更改保持在最低限度。(新类/函数/等可能会根据需要变得复杂。) 例如: if dict1 != dict2: rai
if dict1 != dict2:
raise DataMismatch
dict1!=需要重写dict2
条件,以便使用近似相等函数而不是\uuuuuuuueq\uuuuuu
比较dict1和dict2值中使用的任何浮点
词典的实际内容来自各种来源(解析文件、计算等)
注意:我了解了如何覆盖内置浮点的eq。这本来是一个简单的解决方案,但我了解到Python不允许重写内置类型的“
\uuuuuueq\uuuu
运算符”。因此出现了这个新问题。改变内置容器检查相等方式的唯一途径是使它们包含为值,而不是“原始”包装的值(包装在一个覆盖\uuuuuuueq\uuu
和的类中)。如果您需要更改容器本身使用相等性检查的方式,例如,为了在
运算符中使用,其中右侧的操作数是一个列表——以及容器中的方法,例如它们自己的\uuueq\uuuuu(类型(x)。\uuuuueq\uuuuuy)
是Python在内部执行代码的典型方式
如果您所说的是执行您自己的相等性检查(不改变容器本身内部执行的检查),那么唯一的方法就是将每个cont1==cont2
更改为(例如,相同(cont1,cont2,value\u-same)
其中value\u same
是一个接受两个值并返回True
或False
的函数,与=
类似。这可能比您指定的标准更具侵略性
如果您可以更改容器本身(即,创建容器对象的位置数远小于检查两个容器是否相等的位置数),那么使用覆盖\uuuuueq\uuueq
的容器子类是最好的
例如:
(与我在A的第2段中提到的相同)和
(等等,对于您需要的其他容器类型),然后无论您在哪里(例如)
换成
x = EqM_list(someiter)
还要确保捕获创建列表对象的其他方法,例如替换
x = [bah*2 for bah in buh]
与
及
与
等等
是的,我知道,这太麻烦了——但Python的一个核心原则(和实践;-)是内置类型(无论是容器还是诸如float
之类的值类型)本身无法更改。这与Ruby和Javascript的理念截然不同(我个人更喜欢它,但我确实看到它有时似乎有局限性!)
Edit: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))
请注意,这适用于值,根据要求,不到键。“模糊化”dict键(或集合成员)的相等性比较是一个真正的问题。这样看:首先,你如何绝对肯定地保证samevalue(a,b)和samevalue(b,c)
完全暗示并确保samevalue(a,c)
?这种可传递性条件并不适用于我所见过的大多数半合理的“模糊比较”,但对于基于哈希表的容器(如dict和set),它是完全不可或缺的。如果你越过了这个障碍,那么让散列值以某种方式“神奇地”一致的噩梦就会出现——如果一个dict中的两个实际不同的键“映射”到另一个dict中相同的键,那么应该使用两个对应的值中的哪一个。。。?如果你问我的话,这种疯狂就是谎言,所以我希望当你说值时,你的意思是,确切地说,值,而不是键!) 你的问题是什么?如果你已经有了这个函数,有什么问题吗?你能提供一些你希望以不同方式工作的示例代码吗?已经回答:是的,我指的是值而不是键。。更正问题:)是的,我没有想到你提到的钥匙有问题;一想到这件事,我就意识到这会像你说的那样是一场灾难。幸运的是,没有人使用浮点数作为键(或者换句话说,没有人疯了),所以一切都很好。
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())
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))