Python “与”之间有区别吗==&引用;及;“是”吗;?
我的工作让我失望 在Python中,以下两个相等测试是否等效Python “与”之间有区别吗==&引用;及;“是”吗;?,python,reference,equality,semantics,Python,Reference,Equality,Semantics,我的工作让我失望 在Python中,以下两个相等测试是否等效 n = 5 # Test one. if n == 5: print 'Yay!' # Test two. if n is 5: print 'Yay!' 对于要比较实例的对象(如列表)来说,这是否成立 好的,这样回答了我的问题: L = [] L.append(1) if L == [1]: print 'Yay!' # Holds true, but... if L is [1]: print
n = 5
# Test one.
if n == 5:
print 'Yay!'
# Test two.
if n is 5:
print 'Yay!'
对于要比较实例的对象(如列表)来说,这是否成立
好的,这样回答了我的问题:
L = []
L.append(1)
if L == [1]:
print 'Yay!'
# Holds true, but...
if L is [1]:
print 'Yay!'
# Doesn't.
因此,=
测试所在位置的值
测试它们是否是相同的对象?=
确定值是否相等,而is
确定它们是否是完全相同的对象。
is
测试身份
=
平等性测试
每个(小)整数值都映射到单个值,因此每3个值都相同且相等。这是一个实现细节,不是语言规范的一部分,尽管如果两个变量指向同一个对象,将返回True
,如果变量引用的对象相等,=
>>> a = [1, 2, 3]
>>> b = a
>>> b is a
True
>>> b == a
True
# Make a new copy of list `a` via the slice operator,
# and assign it to variable `b`
>>> b = a[:]
>>> b is a
False
>>> b == a
True
在您的例子中,第二个测试只起作用,因为Python缓存小整数对象,这是一个实现细节。对于较大的整数,这不起作用:
>>> 1000 is 10**3
False
>>> 1000 == 10**3
True
字符串文字也是如此:
>>> "a" is "a"
True
>>> "aa" is "a" * 2
True
>>> x = "a"
>>> "aa" is x * 2
False
>>> "aa" is intern(x*2)
True
请同时查看。您的答案是正确的。is
操作符比较两个对象的标识。=
操作符比较两个对象的值
对象的标识在创建后不会改变;您可以将其视为对象在内存中的地址
您可以通过定义\uuu cmp\uuu
方法或类似\uuuu eq\uuuu的方法来控制对象值的比较行为。它们完全不同is检查对象标识,而=
检查相等性(这一概念取决于两个操作数的类型)
这只是一个幸运的巧合,“is
”似乎可以正确处理小整数(例如5==4+1)。那是因为。这种行为完全依赖于实现,不能保证在所有形式的小型转换操作下都能保持
例如,Python 3.5也将短字符串设置为单例,但对它们进行切片会破坏此行为:
>>> "foo" + "bar" == "foobar"
True
>>> "foo" + "bar" is "foobar"
True
>>> "foo"[:] + "bar" == "foobar"
True
>>> "foo"[:] + "bar" is "foobar"
False
看看堆栈溢出问题
它主要归结为“is
”检查它们是否是相同的对象,而不仅仅是彼此相等(256以下的数字是特例)。有一个简单的经验法则告诉您何时使用=
或is
=
表示值相等。当您想知道两个对象是否具有相同的值时,请使用它
是
用于参考等式。如果您想知道两个引用是否引用同一个对象,请使用它
通常,当您将某个内容与简单类型进行比较时,通常会检查值是否相等,因此应该使用==
。例如,您的示例的目的可能是检查x的值是否等于2(=
),而不是x
是否字面上指的是与2相同的对象
还要注意的是:由于CPython引用实现的工作方式,如果您错误地使用is
来比较整数上的引用相等性,您将得到意外和不一致的结果:
>>> a = 500
>>> b = 500
>>> a == b
True
>>> a is b
False
这正是我们所期望的:a
和b
具有相同的值,但是不同的实体。但是这个呢
>>> c = 200
>>> d = 200
>>> c == d
True
>>> c is d
True
这与先前的结果不一致。这是怎么回事?由于性能原因,Python的参考实现将-5..256范围内的整数对象缓存为单例实例。下面是一个例子来说明这一点:
>>> for i in range(250, 260): a = i; print "%i: %s" % (i, a is int(str(i)));
...
250: True
251: True
252: True
253: True
254: True
255: True
256: True
257: False
258: False
259: False
这是不使用is
的另一个明显原因:当您错误地将其用于值相等时,行为将由实现决定。正如John Feminella所说,大多数情况下,您将使用==和!=因为你的目标是比较价值观。我只想把你剩下的时间会做的事情分类:
NoneType只有一个实例,即None是单例。因此,foo==None
和foo是None
意味着相同。然而,is
测试速度更快,Pythonic惯例是使用fooisnone
如果你在做一些内省,或者在垃圾收集方面胡闹,或者检查你定制的string interning小工具是否正常工作,那么你可能有一个foo
isbar
的用例
True和False(现在)也是单例,但是没有foo==True的用例,也没有foo为True的用例
Python中的==
和Is
之间有区别吗?
是的,它们有一个非常重要的区别
>>> a = b = [1,2,3]
>>> c = [1,2,3]
>>> a == b
True
>>> a == c
True
>>> a is b
True
>>> a is c
False
>>> a = [1,2,3]
>>> b = [1,2]
>>> a == b
False
>>> a is b
False
>>> del a[2]
>>> a == b
True
>>> a is b
False
=
:检查相等性-语义是等价对象(不一定是同一对象)将测试为相等。作为:
运算符,==,>=,与=
之间的区别是什么?
=
和是不同的比较!正如其他人已经说过的那样:
=
比较对象的值
is
比较对象的引用
在Python中,名称指对象,例如在本例中,value1
和value2
指存储值1000
的int
实例:
value1 = 1000
value2 = value1
因为value2
引用了相同的对象is
,=
将给出True
:
>>> value1 == value2
True
>>> value1 is value2
True
在以下示例中,名称value1
和value2
引用不同的int
实例,即使两者存储相同的整数:
>>> value1 = 1000
>>> value2 = 1000
因为存储了相同的值(整数)==
将为True
,这就是原因
>>> [nan] == [nan]
True
>>> (nan,) == (nan,)
True
value1 = 1000
value2 = value1
>>> value1 == value2
True
>>> value1 is value2
True
>>> value1 = 1000
>>> value2 = 1000
>>> value1 == value2
True
>>> value1 is value2
False
class MyClass(object):
def __init__(self, val):
self._value = val
def __eq__(self, other):
print('__eq__ method called')
try:
return self._value == other._value
except AttributeError:
raise TypeError('Cannot compare {0} to objects of type {1}'
.format(type(self), type(other)))
>>> MyClass(10) == MyClass(10)
__eq__ method called
True
class AClass(object):
def __init__(self, value):
self._value = value
>>> a = AClass(10)
>>> b = AClass(10)
>>> a == b
False
>>> a == a
>>> import numpy as np
>>> np.arange(10) == 2
array([False, False, True, False, False, False, False, False, False, False], dtype=bool)
Yes: if greeting:
No: if greeting == True:
Worse: if greeting is True:
str = 'hello'
if (str is 'hello'):
print ('str is hello')
if (str == 'hello'):
print ('str == hello')
str is hello
str == hello
str2 = 'hello sam'
if (str2 is 'hello sam'):
print ('str2 is hello sam')
if (str2 == 'hello sam'):
print ('str2 == hello sam')
str2 == hello sam
str = 'hello'
id('hello')
> 140039832615152
id(str)
> 140039832615152
str2 = 'hello sam'
id('hello sam')
> 140039832615536
id(str2)
> 140039832615792
list1 = [1,2,3,4]
tuple1 = (1,2,3,4)
print(list1)
print(tuple1)
print(id(list1))
print(id(tuple1))
print(list1 == tuple1)
print(list1 is tuple1)
a=[1,2,3]
b=a #a and b point to the same object
c=list(a) #c points to different object
if a==b:
print('#') #output:#
if a is b:
print('##') #output:##
if a==c:
print('###') #output:##
if a is c:
print('####') #no output as c and a point to different object
>>> a = b = [1,2,3]
>>> c = [1,2,3]
>>> a == b
True
>>> a == c
True
>>> a is b
True
>>> a is c
False
>>> a = [1,2,3]
>>> b = [1,2]
>>> a == b
False
>>> a is b
False
>>> del a[2]
>>> a == b
True
>>> a is b
False
Tip: Avoid using is operator for immutable types such as strings and numbers, the result is unpredictable.