协慌网

登录 贡献 社区

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

我有一个 Python 程序,其中两个变量设置为值'public' 。在条件表达式中,我有比较var1 is var2失败,但如果我将其更改为var1 == var2则返回True

现在,如果我打开我的 Python 解释器并进行相同的 “是” 比较,它就会成功。

>>> s1 = 'public'
>>> s2 = 'public'
>>> s2 is s1
True

我在这里错过了什么?

答案

is身份测试, ==是平等测试。您的代码中会发生什么,将在解释器中模拟如下:

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

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

换句话说: isid(a) == id(b)

这里的其他答案是正确的: is用于身份比较,而==用于相等比较。因为你关心的是相等(两个字符串应该包含相同的字符),在这种情况下, is运算符是完全错误的,你应该使用==代替。

究其原因is作品交互的是,(大多数)字符串文字拘留默认。来自维基百科:

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

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

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

is关键字是对象标识的测试,而==是值比较。

如果使用is ,则当且仅当对象是同一对象时,结果才为真。但是,只要对象的值相同, ==就为真。