提问者:小点点

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


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

现在如果我打开我的Python解释器并做同样的“is”比较,它就成功了。

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

我错过了什么?


共3个答案

匿名用户

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

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

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

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

匿名用户

这里的其他答案都是正确的:is用于同一性比较,而==用于相等性比较。 由于您关心的是相等性(两个字符串应该包含相同的字符),因此在本例中,is运算符是错误的,您应该使用==

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

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

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

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

匿名用户

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

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