代码之家  ›  专栏  ›  技术社区  ›  Arashi

不使用运算符的相等

  •  1
  • Arashi  · 技术社区  · 11 年前

    有人问我,是否可以在不调用运算符的情况下比较两个列表,以确定它们是否相同(或者更确切地说,包含相同的元素)。

    我第一次用

    x in y
    

    在我意识到它不在乎秩序,只在乎存在之前。当然,如果列表中包含纯数字,那么进行模数测试是很简单的,但是列表中可以包含字符串。(它也不起作用,但我真的没想到它会起作用,因为它测试身份…)

    所以我想知道,不使用运算符(==,!=)是否可以(甚至)完成等式测试?

    这只是一个反问,但它已经折磨了我一段时间,我已经放弃了用我不太广泛的python知识自己解决它。

    2 回复  |  直到 11 年前
        1
  •  9
  •   Martijn Pieters    11 年前

    当然可以,只需绕过操作员,直接前往 __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 对于相等的值。 任意() 回报 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
    

    这是因为 映射() 压缩列表中的值,并将这些值对传递给第一个参数,一个可调用参数。这将减去值,只有当整数相等时,我们才能得到所有值 0 价值观和 任意() 回报 错误 .

        2
  •  0
  •   venpa    11 年前

    除了Martijn Pieters的回答,我还可以考虑以下选项:

    使用XOR:

    x = [1, 2, 3]
    y = [1, 2, 3]
    result = "list equal"
    if len(x)-len(y):
        result = "list not equal"
    else:
        for i,j in zip(x,y):
            if i ^ j: 
                result = "list is not equal"
                break
    print result
    

    使用集合:

    if set(x).difference(set(y)):
        print "list not equal"
    else:
        print "list equal"