Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 内置容器的自定义比较_Python_Comparison - Fatal编程技术网

Python 内置容器的自定义比较

Python 内置容器的自定义比较,python,comparison,Python,Comparison,在我的代码中,对各种容器(list、dict等)的相等性进行了大量比较。容器的键和值的类型为float、bool、int和str。内置==和!=工作得非常好 我刚刚了解到,容器值中使用的浮点数必须使用自定义比较函数进行比较。我已经编写了该函数(我们将其称为approxEqual(),并假设它需要两个浮点,如果判断它们相等,则返回True,否则返回False) 我希望对现有代码的更改保持在最低限度。(新类/函数/等可能会根据需要变得复杂。) 例如: if dict1 != dict2: rai

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

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

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

例如:

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