运算符
is
与变量的值不匹配,但它们的实例本身不匹配。了解Python的“is”运算符
这是什么意思?
我声明了一个名为x
和y
在两个变量分配相同的值的两个变量,但是当我用is
运算符返回false。
我需要澄清。这是我的代码。
x = [1, 2, 3]
y = [1, 2, 3]
print x is y #It prints false!
运算符
is
与变量的值不匹配,但它们的实例本身不匹配。了解Python的“is”运算符
这是什么意思?
我声明了一个名为x
和y
在两个变量分配相同的值的两个变量,但是当我用is
运算符返回false。
我需要澄清。这是我的代码。
x = [1, 2, 3]
y = [1, 2, 3]
print x is y #It prints false!
您误解了is
操作员测试的内容。它测试两个变量是否指向相同的对象,而不是两个变量具有相同的值。
从文档的is
operator:
运营商
is
和对象标识is not
试验:x is y
当且仅当x
和y
是同一对象是真实的。
使用==
操盘手:
print x == y
这将打印True
。 x
和y
是两个独立的名单:
x[0] = 4
print y # prints [1, 2, 3]
print x == y # prints False
如果使用id()
function你会看到x
和y
有不同的标识符:
>>> id(x)
4401064560
>>> id(y)
4401098192
,但如果你要分配给y
x
那么两者都指向相同的对象:
>>> x = y
>>> id(x)
4401064560
>>> id(y)
4401064560
>>> x is y
True
和is
显示两者是相同的对象,它返回True
。
X指向一个数组,Y指向不同的数组。这些数组是相同的,但运算符会查看那些不相同的指针。
Python没有指针。你需要加强你的术语。 –
它在内部执行,就像Java和许多其他语言一样。事实上,''''运算符的功能显示了这一点。 – Neko
实现细节不重要。该文档使用术语“对象标识”。你应该如此。 “操作符是和不是测试对象的身份:当且仅当x和y是同一个对象时,x是y是真的,x不是y产生反真值。 –
它比较对象标识,也就是变量是否引用内存中的同一个对象。它就像是Java或C中的==
(比较指针时)。
正如你可以在这里检查一个小整数。高于257的数字不是一个小数,因此它被计算为一个不同的对象。
在这种情况下,最好使用==
。
进一步的信息是在这里:http://docs.python.org/2/c-api/int.html
is
只有当它们实际上是同一个对象返回true。如果它们是相同的,那么对另一个的改变也会出现。这是一个差异的例子。
>>> x = [1, 2, 3]
>>> y = [1, 2, 3]
>>> print x is y
False
>>> z = y
>>> print y is z
True
>>> print x is z
False
>>> y[0] = 5
>>> print z
[5, 2, 3]
由duplicate question提示,这个比喻可能工作:
# - Darling, I want some pudding!
# - There is some in the fridge.
pudding_to_eat = fridge_pudding
pudding_to_eat is fridge_pudding
# => True
# - Honey, what's with all the dirty dishes?
# - I wanted to eat pudding so I made some. Sorry about the mess, Darling.
# - But there was already some in the fridge.
pudding_to_eat = make_pudding(ingredients)
pudding_to_eat is fridge_pudding
# => False
可能只是个人品味(没有双关语意思),但我发现这个比喻比困难比有帮助,让我想吃布丁,当我没有在我的冰箱里:( 我认为马克兰森的答案,虽然更多无聊,可能更有教育意义 –
@Tom关闭:对这个问题有很多好的答案,足以让我有轻松的空间,而且我也想要布丁 – Amadan
Another duplicate是问为什么两个相等的字符串一般不相同的,这是不是真的在这里回答:
>>> x = 'a'
>>> x += 'bc'
>>> y = 'abc'
>>> x == y
True
>>> x is y
False
那么,他们为什么不是同一个字符串呢?尤其是考虑到这一点:
>>> z = 'abc'
>>> w = 'abc'
>>> z is w
True
让我们推迟了第二部分的位。第一个怎么可能是真的?
解释器必须有一个“实习表”,一个将字符串值映射到字符串对象的表,所以每次尝试使用'abc'
的内容创建一个新字符串时,都会得到相同的对象。 Wikipedia有关如何实习的更详细的讨论。
And Python has string interning table;您可以使用sys.intern
方法手动实习字符串。
事实上,Python是允许自动实习生任何一成不变的类型,但不能要求这样做。不同的实现会实习不同的值。如果你不知道你正在使用哪个实现,CPython会自动实现小整数和一些特殊的单例如False
,但不是字符串(或大整数或小元组,或者是小元组,或者是小元组,或者是小元组,还要别的吗)。你可以很容易地看到这一点:
>>> a = 0
>>> a += 1
>>> b = 1
>>> a is b
True
>>> a = False
>>> a = not a
>>> b = True
a is b
True
>>> a = 1000
>>> a += 1
>>> b = 1001
>>> a is b
False
OK,但为什么是z
和w
相同?
这不是解释器自动实习,这是编译器折叠值。
如果相同的编译时间字符串在同一模块中出现两次(究竟这意味着很难定义,它是不一样的事,作为一个字符串字面量,因为r'abc'
,'abc'
,并且'a' 'b' 'c'
都是不同的文字,但相同的字符串 - 但直观易懂),编译器将只创建一个字符串实例,并带有两个引用。
事实上,编译器可以走得更远:'ab' + 'c'
可以被优化,在这种情况下,它可以与在同一模块中的'abc'
常数被折叠转换为'abc'
。
同样,这是Python允许但不是必须做的事情。但在这种情况下,CPython总是折叠小字符串(也是小元组)。 (虽然交互式解释的声明逐言编译器不运行相同的优化为模块-AT-一个即时编译器,所以你不会看到完全相同的结果交互。)
所以,作为程序员你应该怎么做?
呃...没什么。如果两个不可变的值是相同的,你几乎从不会有任何理由关心。如果你想知道什么时候可以使用a is b
而不是a == b
,那么你问的是错误的问题。只是一直使用a == b
除了在两种情况下:
x is None
。x
是否会影响y
。is
and is not
是Python中的两个身份运算符。 is
运算符不会比较变量的值,但会比较变量的身份。试想一下:
>>> a = [1,2,3]
>>> b = [1,2,3]
>>> hex(id(a))
'0x1079b1440'
>>> hex(id(b))
'0x107960878'
>>> a is b
False
>>> a == b
True
>>>
上面的例子显示,你的身份(也可以在CPython的内存地址)是两个a
和b
不同(即使它们的值是相同的)。这就是为什么当你说a is b
时,由于两个操作数的身份不匹配,它会返回错误。但是,当您说a == b
时,它会返回true,因为==
操作仅验证两个操作数是否具有分配给它们的相同值。
有趣的例子(为特级):
>>> del a
>>> del b
>>> a = 132
>>> b = 132
>>> hex(id(a))
'0x7faa2b609738'
>>> hex(id(b))
'0x7faa2b609738'
>>> a is b
True
>>> a == b
True
>>>
在上面的例子中,即使a
和b
是两个不同的变量,a is b
回到True
。这是因为a
的类型是int
这是一个不可变的对象。所以python(我想要节省内存)分配相同的对象b
当它被创建具有相同的值。所以在这种情况下,变量的身份匹配和a is b
竟然是True
。
这将适用于所有不可变对象:
>>> del a
>>> del b
>>> a = "asd"
>>> b = "asd"
>>> hex(id(a))
'0x1079b05a8'
>>> hex(id(b))
'0x1079b05a8'
>>> a is b
True
>>> a == b
True
>>>
希望有所帮助。
这是一个很好的例子,谢谢你的详细信息 – Haranadh
但是试试 a = 123456789 b = 123456789 – user2183078
x is y
与id(x) == id(y)
相同,比较对象的身份。
相关问题http://stackoverflow.com/questions/38189660/two-variables-in-python-have-same-id-but-not-lists-or-tuples-why/38189759#38189759 – Kasramvd