Python中的字符串比较:is vs. == [重复]

Posted

技术标签:

【中文标题】Python中的字符串比较:is vs. == [重复]【英文标题】:String comparison in Python: is vs. == [duplicate] 【发布时间】:2011-02-28 14:28:15 【问题描述】:

我注意到我正在编写的一个 Python 脚本运行异常,并将其追踪到一个无限循环,其中循环条件为 while line is not ''。在调试器中运行它,结果发现该行实际上是''。当我将其更改为 !='' 而不是 is not '' 时,它运行良好。

此外,即使在比较 int 或 Boolean 值时,通常认为默认使用 '==' 是否更好?我一直喜欢使用'is',因为我发现它在美学上更令人愉悦和pythonic(这就是我陷入这个陷阱的原因......),但我想知道它是否只是为了当你关心找到两个时保留具有相同 id 的对象。

【问题讨论】:

这个“与您的经验相反”如何? NaN 是唯一内置的反例;你只是误解了方向关系。规范说“对于所有内置 Python 对象(如字符串、列表、字典、函数等),如果 x 是 y,那么 x==y 也是 True。”,而不是“对于所有内置 Python 对象(如字符串、列表、字典、函数等),如果 x==y,则 x 是 y 也是 True。”出于某种原因,您假装它说的是后者。它没有。您会看到相等匹配,但不匹配。前面引用的声明完全允许这样做。 是的。我的阅读完全混乱。我编辑了它,因为我认为它对未来的读者没有用。 o1 is o2 => 比较 o1 和 o2 是否都指向内存中的相同物理位置(换句话说,如果它们是相同的对象)。而 o1 == o2 => 这里 python 调用 o1 的 __cmp__(o2) 方法,理想情况下应该比较值并返回 True 或 False。 (也就是说它比较值) 对于 JAVA 人:在 Java 中,通过使用 str1 == str2 来确定两个字符串变量是否引用相同的物理内存位置。 (称为对象标识,它是用 Python 编写的,因为 str1 是 str2)。要在 Java 中比较字符串值,请使用 str1.equals(str2);在 Python 中,使用 str1 == str2。 【参考方案1】:

我想展示一个关于is== 如何参与不可变类型的小例子。试试看:

a = 19998989890
b = 19998989889 +1
>>> a is b
False
>>> a == b
True

is 比较内存中的两个对象,== 比较它们的值。例如,您可以看到 Python 缓存了小整数:

c = 1
b = 1
>>> b is c
True

比较值时应使用==,比较身份时应使用is。 (另外,从英语的角度来看,“equals”与“is”不同。)

【讨论】:

另一个简单的例子,datetime.date.today() == datetime.date.today() ==> True 但datetime.date.today is datetime.date.today() ==> False 因为它们是等效的日期对象,但它们仍然是不同的对象。 您的建议避免的另一个危险示例:str(None) is 'None' 的计算结果为 False,但 str(None) == 'None' 的计算结果为 True 这是一个带字符串的:x = 'foo'; y = 'bar'.replace('bar', 'foo'); (x is y) == False 另一个我喜欢的例子:'a'*50 == 'a'*50(返回 True),而 'a'*50 是 'a'*50(返回 False)【参考方案2】:

对于所有内置的 Python 对象(如 字符串、列表、字典、函数、 等),如果 x 是 y,那么 x==y 也是 没错。

并非总是如此。 NaN 是一个反例。但是通常,身份 (is) 意味着平等 (==)。反之则不成立:两个不同的对象可以具有相同的值。

此外,通常认为默认情况下只使用“==”更好吗? 比较 int 或 Boolean 值时?

比较值时使用==,比较身份时使用is

在比较整数(或一般的不可变类型)时,您几乎总是想要前者。有一个优化允许将小整数与is 进行比较,但不要依赖它。

对于布尔值,您根本不应该进行比较。而不是:

if x == True:
    # do something

写:

if x:
    # do something

为了与None 进行比较,is None 优于 == None

我一直喜欢用“is”,因为 我觉得它更美观 和 pythonic (这就是我陷入 这个陷阱......),但我想知道它是否是 打算只保留在什么时候 你关心找到两个对象 具有相同的 id。

是的,这正是它的用途。

【讨论】:

@Coquelicot:这行不通,因为 Python 允许将任何东西用作布尔表达式。如果你有 bool_a == 3 和 bool_b == 4,那么 bool_a != bool_b,但 bool_a xor bool_b 是假的(因为这两个条件都是真的)。​​ @Mike:x is x 始终为真。但这并不意味着x == x。 NaN 被定义为不等于自身。 关于速度,我认为检查字符串是否被修改(例如,从 re.sub 返回的结果)比较大字符串的is 相等性而不是== 会更快。几乎没有这种情况,它只显示了 0.4% 的速度提升。就我而言,不值得冒 re.sub 将来开始更改字符串的风险。 对于那些年后看的人来说,这仍然适用于 Python 3。 @beauxq:试试nan = float('nan'); nan is nan; nan == nan【参考方案3】:

逻辑没有缺陷。声明

如果 x 是 y,那么 x==y 也是 True

不应该将永远理解为

如果 x==y 那么 x 就是 y

假设一个逻辑语句的反面是正确的,这是读者的逻辑错误。见http://en.wikipedia.org/wiki/Converse_(logic)

【讨论】:

@BrentHronik 更多的是与对象的内存地址和id有关,而不是实际逻辑。 如果 x 和 y 都是 NaN,那么第一个语句是否为真?甚至可能具有相同的对象ID?在其他语言 (C++) 中,应该是 NaN 永远不等于自身的情况。【参考方案4】:

见This question

你的阅读逻辑

对于所有内置的 Python 对象(如 字符串、列表、字典、函数、 等),如果 x 是 y,那么 x==y 也是 没错。

有点瑕疵。

如果is 适用,那么== 将为True,但它不会反过来应用。 == 可能产生 True,而 is 产生 False。

【讨论】:

is 暗示 == 仅对内置类型必须为真。可以轻松编写一个对象不等于自身的类。 通过说“如果is 适用,那么== 将为真,但它不会反过来应用。”您只是在说明 OP 观察到的内容。

以上是关于Python中的字符串比较:is vs. == [重复]的主要内容,如果未能解决你的问题,请参考以下文章

python中的 == 和 is 的区别

Python之字符串比较is==__cmp__

python字符串,赋值和is的区别

python之is 和 == 的区别//编码和解码

字符串比较逻辑Python [重复]

python中的"is"与"=="比较