有人问我是否可以在不调用运算符的情况下比较两个(比如说)列表,以确定它们是否相同(或者更确切地说,包含相同的元素)。
我第一次使用
x in y
在我意识到它不关心秩序,只关心存在之前。当然,如果列表只包含数字,那么进行模数测试就很简单了,但是列表可以包含字符串。 (也没有用,但我真的没想到,考虑到它测试身份...)
所以我想知道是否(甚至)可以在不使用运算符(==、!=)的情况下完成相等性测试?
这只是一个修辞问题,但它困扰了我一段时间,我宁愿放弃尝试用我不太广泛的 Python 知识自己解决它。
请您参考如下方法:
当然可以,只需绕过运算符直接进入 __eq__特殊方法:
>>> x = [1, 2, 3]
>>> y = [1, 2, 3]
>>> x.__eq__(y)
True
>>> z = [42]
>>> x.__eq__(z)
False
您还可以使用 operator module :
>>> import operator
>>> operator.eq(x, y)
True
>>> operator.eq(x, z)
False
在 Python 2 中,您可以将循环与 any() 结合使用和 cmp() , 与 itertools.izip_longest() 确保我们不会忽略不均匀的长度:
>>> from itertools import izip_longest
>>> not any(cmp(i, j) for i, j in izip_longest(x, y, fillvalue=object()))
True
>>> not any(cmp(i, j) for i, j in izip_longest(x, z, fillvalue=object()))
False
这是有效的,因为 cmp()返回 0对于相等的值。 any()返回 False仅当所有结果均为假(例如 0)时。
见鬼,直奔cmp() 没有循环:
>>> not cmp(x, y)
True
>>> not cmp(x, z)
False
对于 Python 3,您必须创建自己的 cmp()函数,也许使用 .__lt__和 .__gt__如果你想避免 <和 >运营商也是如此。
对于只有整数的列表,你可以放弃 cmp()函数并直接进行减法;让我们使用 map()在这里并包括列表长度:
>>> not (len(x) - len(y)) and not any(map(lambda i, j: i - j, x, y))
True
>>> not (len(x) - len(z)) and not any(map(lambda i, j: i - j, x, z))
False
这是有效的,因为 map()压缩列表中的值并将这些对传递给第一个参数,一个可调用的。减去值,只有当整数相等时,我们才能得到所有 0值和 any()返回 False .
