【问题标题】:Python's preferred comparison operatorsPython 的首选比较运算符
【发布时间】:2010-04-05 03:48:18
【问题描述】:

是否愿意这样做:

if x is y:
    return True

if x == y
    return True

“不是”也一样

【问题讨论】:

    标签: python comparison


    【解决方案1】:

    x is yx == y 不同。

    x is y 为真当且仅当id(x) == id(y)——即xy 必须是同一个对象(具有相同的ids)。

    对于所有内置的 Python 对象(如字符串、列表、字典、函数等),如果 x is y,则 x == y 也是 True。但是,这一般不能保证。严格来说,x == y 为真当且仅当x.__eq__(y) 返回真。

    例如,可以使用始终返回 False 的 __eq__ 方法定义对象 x,这将导致 x == y 返回 False,即使 x is y 也是如此。

    所以底线是,x is yx == y 是完全不同的测试。

    举个例子:

    In [1]: 0 is False
    Out[1]: False
    
    In [2]: 0 == False
    Out[2]: True
    

    PS。而不是

    if x is y:
        return True
    else:
        return False
    

    写起来更Pythonic

    return x is y
    

    同样,

    if x == y:
        return True
    else:
        return False
    

    可以替换为

    return x == y
    

    【讨论】:

    • 我有点挑剔,但在x is y 为真之前,您需要x == y 为真是不正确的。它们是独立的测试。诚然,在实践中你很难找到一个合理的反例,但 __eq__ 特殊方法可能只返回 False 或引发异常。
    【解决方案2】:

    x is y比较两个对象的身份,问'xy是同一个对象的不同名字吗?'相当于id(x) == id(y)

    x == y 使用相等运算符并提出更宽松的问题'xy 是否相等?' 对于用户定义的类型,它等价于x.__eq__(y)

    __eq__ 特殊方法应该表示对象的“相等”,例如表示分数的类希望 1/2 等于 2/4,即使“半”对象不能具有相同的标识作为“两个季度”的对象。

    请注意,不仅a == b 不暗示a is b,反之亦然。一个通常并不比另一个更严格的要求。是的,这意味着如果你真的想要,你可以让a == a 返回False,例如:

    >>> a = float('nan')
    >>> a is a
    True
    >>> a == a
    False
    

    尽管is 在实践中几乎总是比== 更具体。

    【讨论】:

    • 分数的例子真的很到位,伟大的斯科特。 :)
    【解决方案3】:
    • ==!= 是对象比较运算符
    • isis not 是对象 identity 比较运算符

    正如其他人已经说过的,is(和 is not)只有在您真正关心一对变量时指的是完全相同的对象。在大多数情况下,你根本不在乎,所以你会使用 ==!=

    但是,如果您查看大量 Python 代码,您可能会开始注意到,is(和 is not)更有可能在与TrueFalseNone 进行比较时使用。主要原因是这些对象是单例的,这意味着每个值都只有一个实例。为什么这很重要?好吧,这导致了另一个原因……速度。

    对于 ==!=,解释器必须提取两个引用的对象才能进行比较(它们是否相同或不是),而 isis not 只需检查它们所指对象的值。话虽如此,您可以看到后一对将执行得更快,因为您不必自己获取对象来进行比较。这是几年前的一次速度测试,我们得出的结论是,对于一次性,这没什么大不了的,但如果它在一个紧密的循环中被称为无数次,那么它就会开始累加。

    http://mail.python.org/pipermail/tutor/2008-June/062708.html

    底线是您可以使用对象身份比较来检查TrueFalseNone,其他所有内容都应使用直接相等运算符。我们不会在这里讨论内部整数或绑定实例方法,或类似的东西。 :-)

    【讨论】:

    • 与单身人士比较的好点。关于速度,值得注意的是if a == True:if a is True: 慢,后者又比if a: 慢(至少对于我测试中的内置类型)。通常只使用anot a 是最快的选择,尽管它们在语义上与a is Truea is None 等不太一样。
    • 那么,比较整数呢,比如1 is 11 == 1
    • 尽管在range(-5, 256) 中使用小整数(当前)时它们都是等价的,但这些不是公开的数字,并且可以在任何版本中更改,所以只使用== 更安全除了NoneTrueFalse(可能还有其他一些情况)以外的情况。
    • 不幸的是,您不能指望 None 是单身人士。在 PyDev 环境中,您可以拥有许多对象和许多继承层,尤其是在 PyUnit 中,代码由测试运行程序运行,在某些情况下 x is None 会失败,但是 x==None 将按预期工作。字符串也一样。
    • 是的,这仅适用于 CPython 不在 IDE 中执行任何事情。感谢您指出这一点。
    【解决方案4】:

    视情况而定。 isis not 进行身份比较,这对于 NoneEllipsis 或确保两个对象相同是有好处的。否则,请使用==!=

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-11-12
      • 1970-01-01
      • 2021-03-27
      • 1970-01-01
      • 1970-01-01
      • 2016-11-20
      • 2021-10-02
      • 1970-01-01
      相关资源
      最近更新 更多