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. == [重复]的主要内容,如果未能解决你的问题,请参考以下文章