努力理解 is 运算符的特定行为

mic*_*ech 4 python

有人可以向我解释这种行为吗?

a = 'Test'
b = 'Test'
print(a is b)  # True
Run Code Online (Sandbox Code Playgroud)

我预计结果为 False,因为 a 和 b 是不同的引用。当使用相等运算符 (==) 来比较值相等时,我所期望的显示结果。

is-operator 是为了比较引用相等?还是我弄错了?

显示行为的原因是什么?

Kul*_*dhu 6

简而言之:

==用于值相等和is用于引用相等(与 相同id(a)==id(b))。Python 缓存小对象(小整数、字符串等)以节省空间(自 py2 以来的功能)。

我原来的详细答案和例子:

因为它们完全一样!

is如果两个变量指向同一个对象,则返回 True,您可以检查id以了解真相!

尝试这个:

a = 'Test'
b = 'Test'
print(a is b) 
print(id(a),id(b))
Run Code Online (Sandbox Code Playgroud)

我的输出是:

True
140586094600464 140586094600464
Run Code Online (Sandbox Code Playgroud)

因此,为了节省空间 Python 将分配指针相同的位置,直到进行更改

例子:

a = 'Test'
b = 'Test'
print(a is b) 
print(id(a),id(b))
a = 'Test'
b += 'Changed'
print(a is b) 
print(id(a),id(b))
Run Code Online (Sandbox Code Playgroud)
True
140586094600464 140586094600464
False
140586094600464 140585963428528
Run Code Online (Sandbox Code Playgroud)

一旦进行更改,不可变的字符串将在内存中获得新位置!

如果这是类似list,即使它们相同也是可变的,它们将获得不同的位置,因此可以进行更改!

#mutable
a= [1,2]
b= [1,2]
print(a is b) 
print(id(a),id(b))
a[0] = -1
b[1] = -2
print(a is b) 
print(id(a),id(b))
Run Code Online (Sandbox Code Playgroud)
False
140586430241096 140585963716680
False
140586430241096 140585963716680
Run Code Online (Sandbox Code Playgroud)

Int 例如:

a=100 
b=100
print(a is b) 
print(id(a),id(b))
Run Code Online (Sandbox Code Playgroud)
True
10917664 10917664
Run Code Online (Sandbox Code Playgroud)

  • 您也无法修改。字符串是不可变的。 (4认同)
  • “直到做出改变”这部分具有误导性。当字符串之一“更改”时,Python 不会重定向指针。指针只是指向不同的字符串。 (2认同)
  • 还有,“因为他们一模一样!” 是一种粗略的简化,并没有真正回答为什么以及何时确切地汇集字符串(或数字)。例如,如果你执行 `c = a.title()`,c 也与 `a` “完全相同”,但 `a` 不是 `c`。或者,如果您将 `a` 和 `b` 都指定为 `"a" * 5000` (2认同)
  • @SMVaidhyanathan 不。 *string* 是内存中的对象,它不会发生任何变化(直到垃圾收集),并且它肯定不会获得新的位置。改变的是变量的绑定,变量本身没有字符串的概念。 (2认同)