【发布时间】:2012-09-29 11:04:24
【问题描述】:
['hello'] is ['hello'] # gives False
为什么?他们的身份证不一样。为什么元组或数字最终没有返回 False?
【问题讨论】:
标签: python
['hello'] is ['hello'] # gives False
为什么?他们的身份证不一样。为什么元组或数字最终没有返回 False?
【问题讨论】:
标签: python
考虑以下(Python 2.7.3,64 位):
>>> a = "Hello"
>>> b = "Hello"
>>> a is b
True
Python 对短字符串'Hello' 进行实习,只存储一次。这是一个实现细节,语言标准不保证。它可能会在较长的字符串上失败:
>>> a = "this is a long string"
>>> b = "this is a long string"
>>> a is b
False
现在考虑一下:
>>> a = ["Hello"]
>>> b = ["Hello"]
>>> a is b
False
a 和 b 是两个不同的对象。您可以通过id() 进行检查:
>>> id(a)
33826696L
>>> id(b)
33826952L
这是一件好事TM,因为当你这样做时
>>> a[0] = "Goodbye"
>>> a
['Goodbye']
>>> b
['Hello']
但是,如果你这样做了
>>> a = ["Hello"]
>>> b = a
>>> a is b
True
>>> a[0] = "Goodbye"
>>> b
['Goodbye']
因为a 和b 是指同一个对象的名称(id(a) == id(b))。最后,表明即使你得到了
>>> a = ["Hello"]
>>> b = ["Hello"]
>>> a is b
False
字符串仍然被保留并且只存储一次:
>>> id(a[0])
33846096L
>>> id(b[0])
33846096L
【讨论】:
is 运算符测试两个对象引用是否引用同一个对象(它不是相等运算符,而是标识运算符)。在您的示例中,您创建了两个单独的列表,因此您有两个不同的对象,这就是您看到 False 被返回的原因。
【讨论】:
['hello'] 执行两次?
a = ['hello']; b = ['hello'],a is b 将是 False,因为它是两个不同的对象。毕竟,您不希望a[0] = "Goodbye" 影响b,对吗?但是,如果您执行a = ['hello']; b = a,则a is b 将为True,并且a[0] = "Goodbye" 也会影响b。
'hello'通过实习优化,所以只存储一次。但是您的 is 比较不比较字符串,它比较列表!
当您使用[] 语法创建列表时,会创建一个新的列表对象。列表是可变对象,因此,即使两个列表碰巧包含相同的元素,它们也不是相同的对象。您可以观察到,通过调用其中一种修改方法来更改列表实际上不会更改 ID:
In [1]: a = ["hello"]
In [2]: b = ["hello"]
In [3]: id(a)
Out[3]: 4477468112
In [4]: id(b)
Out[4]: 4477467824
In [5]: a.append("world")
In [6]: id(a)
Out[6]: 4477468112
【讨论】:
"For immutable objects, for example strings, different variables will in fact refer to the same object" 这是不正确的。请参阅 Tim Pietzcker 对此的回答。