"x is y"和"x==y"有所不同。
x is y
会检查x和y是否指向堆中的同一对象。
而x == y
将检查x和y的值是否相同。
现在让我们看看为什么你得到了两个不同的结果
如果值的长度很小(最多3到4位数),那么Python只会检查堆中是否存在另一个具有相同值的对象。如果存在,则不会创建新对象,如果不存在,则创建新对象。
如果值的长度很大(超过4位数),Python将创建新对象,而不检查是否已经存在具有相同值的对象。
当字符串、整数或浮点数的长度较小时
在Python中,如果两个变量
具有相同的字符串、整数或浮点数值
,并且值的长度较小
,则两个变量都指向同一个对象,即在堆内存中只创建了一个对象。
通过以下示例进行尝试。
a=10
b=10
a is b
True
a == b
True
这里的a is b
检查a和b是否引用(即指向)堆中的同一对象。
由于10
的长度为2,很小,Python解释器只会创建一个值为10的对象,因此a和b将引用同一对象,输出为True
a == b
将检查a的值是否等于b的值。
由于a的值为10,b的值也为10,因此输出为True
您也可以尝试使用字符串值,例如
s1='abc'
s2='abc'
s1 is s2
True #output
s1 == s2
True #output
当字符串、整数、浮点数很长时
现在,当字符串、整数、浮点数很长时,Python解释器不会检查堆中是否有相同值的对象,即使已经存在带有相同值的对象,它也会直接创建新对象。
x = 'nao;uh gahasjhd;fjkhag;sjdgfuiwgfashksghdfaihghehwq3473fsd_@'
y = 'nao;uh gahasjhd;fjkhag;sjdgfuiwgfashksghdfaihghehwq3473fsd_@'
x is y
False
x == y
True
由于 nao;uh gahasjhd;fjkhag;sjdgfuiwgfashksghdfaihghehwq3473fsd_@
太长,Python 解释器不会检查堆中是否有另一个具有相同值的对象,它将创建一个对象并引用该对象作为 x
。
现在再次将 nao;uh gahasjhd;fjkhag;sjdgfuiwgfashksghdfaihghehwq3473fsd_@
分配给 y
,但是由于字符串长度较大,Python 解释器将创建新对象(即使该对象已存在)
现在,由于 x
和 y
引用不同的对象,输出结果将为 False
由于 x
和 y
具有相同的值,输出结果将为 True
您也可以尝试此示例
a = 10000
b = 10000
a is b
False
a == b
True
为什么Python这样做
Python这样做是为了减少解释时间(即代码执行时间)。如果Python一直检查堆中是否已经存在那个长字符串(例如长度为10的字符串),它将需要更多时间,因为它将逐个字母地与所有对象进行比较。比较10个字符将消耗大量时间。
而如果字符串长度小于4,则很容易进行比较(因为只需要比较3个字母),并且不会花费太多时间。
x is y
或x is not y
在这里为真的任何代码都是错误的,或者最多也是不可移植的。如果您想了解特定实现(如CPython 3.7、CPython 2.7或PyPy 2.1/3.5)的内部实现细节,或者如果您想了解Python实现在这里可能使用的一般方法,那么这些确实是完全独立的问题。 - abarnert