我的Google-fu让我失望了

在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 'Yay!'
# Doesn't.

所以==测试值测试是看他们是否相同的对象?


当前回答

如果两个变量指向同一个对象(在内存中),则返回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之间的区别,用于比较对象或变量,我将主要强调is和==之间的比较,用于字符串,可以给出不同的结果,我将敦促程序员谨慎使用它们。

对于字符串比较,确保使用==而不是is:

str = 'hello'
if (str is 'hello'):
    print ('str is hello')
if (str == 'hello'):
    print ('str == hello')

Out:

str is hello
str == hello

但是在下面的例子中== and is会得到不同的结果:

str2 = 'hello sam'
    if (str2 is 'hello sam'):
        print ('str2 is hello sam')
    if (str2 == 'hello sam'):
        print ('str2 == hello sam')

Out:

str2 == hello sam

结论与分析:

使用的是仔细比较之间的字符串。 因为是用来比较对象的,而且在Python 3+中,每个变量(如字符串)都被解释为对象,让我们看看上面的段落中发生了什么。

在python中,有一个id函数,它显示一个对象在其生命周期内的唯一常数。这个id在Python解释器的后端使用is关键字来比较两个对象。

str = 'hello'
id('hello')
> 140039832615152
id(str)
> 140039832615152

But

str2 = 'hello sam'
id('hello sam')
> 140039832615536
id(str2)
> 140039832615792

看看Stack Overflow问题Python的“is”运算符对整数的行为出人意料。

它主要归结为“is”检查它们是否是相同的对象,而不仅仅是彼此相等(256以下的数字是一个特殊情况)。

如果两个变量指向同一个对象(在内存中),则返回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

请看这个问题。

https://docs.python.org/library/stdtypes.html#comparisons

是身份测试 ==测试是否相等

每一个(小的)整数值都被映射到一个单独的值,所以每3都是相同的。这是一个实现细节,但不是语言规范的一部分

有一个简单的经验法则告诉你什么时候使用==或is。

==表示价值相等。当你想知道两个对象是否有相同的值时使用它。 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

这是不使用的另一个明显原因:当您错误地将其用于值相等时,行为将留给实现。