比较python中的两个字符串时,它工作正常,当比较string
对象和unicode
对象时,它会按预期失败但是将string
对象与转换后的unicode进行比较< em> (unicode --> str)
对象失败
按预期工作:
>>> if 's' is 's': print "Hurrah!"
...
Hurrah!
非常是啊:
>>> if 's' is u's': print "Hurrah!"
...
不期望:
>>> if 's' is str(u's'): print "Hurrah!"
...
为什么当这两个类型属于同一类时,第三个例子是否按预期工作?
>>> type('s')
<type 'str'>
>>> type(str(u's'))
<type 'str'>
答案 0 :(得分:12)
请勿使用is
,请使用==
。您正在比较对象是否具有相同的标识,而不是它们是否相等。当然,如果它们是相同的对象,它们将是相等的(==
),但如果它们相等,则它们不一定是同一个对象。
第一个工作的事实是CPython的实现细节。小字符串,因为它们是不可变的,可以由解释器实现。每次将字符串"s"
放入源代码中时,Cpython都会重用相同的对象。但是,显然str("s")
返回一个具有相同值的新字符串。这并不奇怪。
你可能会问自己,“为什么要对字符串's'
进行实际操作?”。这是一个合理的问题。毕竟,它是一个短小的字符串 - 在你的源代码中有多少内存可以有多个副本?答案(我认为)是因为字典查找。由于字符串作为键的dicts在python中非常常见,因此当指针比较返回false时,可以通过快速指针比较(回落到较慢的strcmp
)来加快键的哈希函数/等式检查。 p>
答案 1 :(得分:3)
is
运算符用于比较两个操作数的内存位置。由于字符串是不可变的,'s'
和's'
占用内存中的相同位置。
由于在python2.7中处理unicode的方式,u's'
和's'
以相同的方式/位置存储。因此,它们占据相同的内存位置。因此's' is u's'
评估为True
。 击>
正如@mgilson指出的那样,'s'
和u's'
属于不同的类型,因此不占用相同的内存位置,导致's' is u's'
评估为False
但是,当您调用str(u's')
时,会创建并返回一个新字符串。这个新字符串因为重新创建而存在于内存中的新位置,这就是is
比较失败的原因。
您真正想要的是检查它们是等效的字符串,因此请使用==
In [1]: 's' == u's'
Out[1]: True
In [2]: 's' == 's'
Out[2]: True
In [3]: 's' == str(u's')
Out[3]: True
答案 2 :(得分:2)
使用==
进行值比较,使用is
进行参考比较。如果对象具有相同的id
,则评估为True
,否则与str()
一样,id
会被更改,因此您获得False
。