为什么使用“==”或“is”比较字符串有时会产生不同的结果?

2022-09-05 00:59:55

两个字符串变量设置为相同的值。 总是返回 ,但有时返回 。s1 == s2Trues1 is s2False

如果我打开我的Python解释器并进行相同的比较,它会成功:is

>>> s1 = 'text'
>>> s2 = 'text'
>>> s1 is s2
True

这是为什么呢?


答案 1

is是身份测试,是平等测试。代码中发生的事情将在解释器中模拟,如下所示:==

>>> a = 'pub'
>>> b = ''.join(['p', 'u', 'b'])
>>> a == b
True
>>> a is b
False

所以,难怪他们不一样,对吧?

换句话说:等效于a is bid(a) == id(b)


答案 2

这里的其他答案是正确的:用于恒等比较,而用于相等比较。由于您关心的是相等性(两个字符串应包含相同的字符),因此在这种情况下,运算符完全错误,您应该改用运算符。is==is==

以交互方式工作的原因是(大多数)字符串文本在默认情况下是暂存的。来自维基百科:is

滞留字符串加快了字符串比较的速度,这有时是严重依赖具有字符串键的哈希表的应用程序(如编译器和动态编程语言运行时)的性能瓶颈。在没有实习的情况下,检查两个不同的字符串是否相等涉及检查两个字符串的每个字符。这很慢,原因有几个:它在字符串的长度上本质上是O(n);它通常需要从内存的几个区域读取,这需要时间;并且读取会填满处理器缓存,这意味着可用于其他需求的缓存更少。对于实习字符串,在原始实习生操作之后,简单的对象标识测试就足够了;这通常实现为指针相等性测试,通常只是一个没有任何内存参考的机器指令。

因此,当您的程序中有两个字符串文本(在程序源代码中按字面意思键入的单词,用引号括起来)具有相同的值时,Python 编译器将自动插入字符串,使它们都存储在相同的内存位置。(请注意,这并不总是发生,并且发生这种情况的规则非常复杂,因此请不要在生产代码中依赖此行为!

由于在交互式会话中,两个字符串实际上都存储在同一内存位置,因此它们具有相同的标识,因此运算符按预期工作。但是,如果您通过其他方法构造字符串(即使该字符串包含完全相同的字符),则该字符串可能相等,但它不是同一个字符串 - 也就是说,它具有不同的标识,因为它存储在内存中的不同位置。is