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

1311

两个字符串变量被赋予相同的值。s1 == s2 永远返回 True,但是 s1 is s2 有时会返回 False

如果我在Python解释器中执行同样的 is 比较,它会成功:

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

为什么会这样?


9
好的,我会尽力而为。以下是需要翻译的内容:问题链接:https://dev59.com/yXM_5IYBdhLWcg3wZSTX问题:在Python中,为什么字符串“hello” == “hello”的结果是True,但是“hello” is “hello”的结果却是False?答案:“==”用于比较值是否相等,“is”用于比较对象是否相同。当创建一个新的字符串时,解释器会在内存中的不同位置创建它,因此使用“is”进行比较时,它们并不相同。但是,对于一些共享的字符串(例如由编译器提前创建的字符串),它们在内存中只有一个实例,因此使用“is”进行比较时会返回True。因此,在大多数情况下,您应该使用“==”来比较字符串的值是否相等,而不是使用“is”来比较它们是否相同的对象。 - Nick Dandoulakis
3
当你通过例如input = raw_input("Decide (y/n): ")来读取控制台输入时,也会出现这个问题。在这种情况下,“y”作为输入并使用if input == 'y':会返回“True”,而使用if input is 'y':会返回False。 - Semjon Mössinger
4
这篇博客比任何答案都提供了更完整的解释:http://guilload.com/python-string-interning/ - Chris_Rands
1
正如@chris-rico所提到的,这里有一个很好的解释https://dev59.com/nWUp5IYBdhLWcg3wEEXd - ThorSummoner
4
可能是Python中'=='和'is'有什么区别吗?的重复问题。 - Taknok
显示剩余2条评论
15个回答

17

我相信这被称为“字符串驻留”。Python、Java、C和C++都会在优化模式下进行编译,如果使用两个相同的字符串,它们会指向同一块内存,而不是浪费内存创建两个字符串对象。

这使得Python的“is”运算符返回True,因为具有相同内容的两个字符串指向同一个字符串对象。这也会发生在Java和C中。

然而,这只对节省内存有用。您不能依赖它来测试字符串的相等性,因为各种解释器、编译器和JIT引擎并不总是能够实现这一点。


是的,这就是我期望的答案。好的,Hari是正确的,但Python是如何做到的呢?感谢Zan进行内存优化。 - CumaTekin
还有.NET(C#VB.NET等)吗? - Peter Mortensen

14
实际上,is 运算符用于检查对象的唯一性,而 == 运算符用于检查相等性。 从语言参考中可以得知:类型几乎影响对象行为的所有方面。甚至某种程度上会影响到对象唯一性的重要性:对于不可变类型而言,计算新值的操作可能实际上会返回引用相同类型和值的任何现有对象,但对于可变对象则不允许这样做。例如,a=1;b=1之后,a和b可能指向同一具有值为1的对象,也可能不是,这取决于具体实现方式;但c=[];d=[]之后,c和d将保证指向两个不同、独立的新创建的空列表。(注意,c=d=[]会将同一对象分配给c和d)。 由此可见,对于字符串、整数和元组这些不可变类型,使用 "is" 检查可能会失败,而使用 "==" 检查可能会成功。

7

is会比较内存地址,用于对象级别比较。

==会比较程序中的变量,用于值级别检查。

is检查内存地址的等价性。

==检查值级别的等价性。


2

is 是身份测试,而 == 是相等性测试(请参见 Python 文档)。

在大多数情况下,如果 a is b,那么 a == b。但是也有例外,例如:

>>> nan = float('nan')
>>> nan is nan
True
>>> nan == nan
False

所以,你只能使用 is 进行身份测试,而不能进行相等性测试。

-4
基本概念是我们需要明确的,在处理这个问题时,要了解is==之间的区别。

"is"将比较内存位置。如果id(a)==id(b),则a is b返回true,否则返回false。

因此,我们可以说is用于比较内存位置。而

==用于相等性测试,这意味着它仅比较结果值。下面显示的代码可以作为以上理论的示例。

代码

Click here for the code

在字符串字面值(未分配给变量的字符串)的情况下,内存地址将与图片中显示的相同。因此,id(a)==id(b)。其余部分是不言自明的。

1
你能直接在代码标签中发布你的代码吗? - flaxel
请查看 *为什么在提问时不上传代码/错误的图片?(例如,"图片应该只用于说明无法以其他方式清晰表达的问题,例如提供用户界面的截图。"*),并采取适当的行动(它也涵盖了答案)。提前致谢。 - Peter Mortensen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接