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

新手上路,请多包涵

两个字符串变量设置为相同的值。 s1 == s2 s1 is s2 False True

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

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

为什么是这样?

原文由 jottos 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 328
2 个回答

is 是身份测试, == 是平等测试。您的代码中发生的事情将在解释器中像这样模拟:

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

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

换句话说: a is b 相当于 id(a) == id(b)

原文由 SilentGhost 发布,翻译遵循 CC BY-SA 4.0 许可协议

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

is 交互工作的原因是(大多数)字符串文字默认是 interned 的。来自维基百科:

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

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

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

原文由 Daniel Pryden 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题