我如何比较unicode类型与python中的字符串?

问题描述:

我想使用比较字符串对象的列表理解,但其中一个字符串是utf-8,json.loads的副产品。场景:我如何比较unicode类型与python中的字符串?

us = u'MyString' # is the utf-8 string 

我的问题的一部分,是为什么这会返回False? :

us.encode('utf-8') == "MyString" ## False 

第二部分 - 如何才能比较列表中的理解?

myComp = [utfString for utfString in jsonLoadsObj 
      if utfString.encode('utf-8') == "MyString"] #wrapped to read on S.O. 

编辑:我使用谷歌应用程序引擎,它使用Python 2.7

这里的问题的一个更完整的例子:我假设你正在使用Python

#json coming from remote server: 
#response object looks like: {"number1":"first", "number2":"second"} 

data = json.loads(response) 
k = data.keys() 

I need something like: 
myList = [item for item in k if item=="number1"] 

#### I thought this would work: 
myList = [item for item in k if item.encode('utf-8')=="number1"] 
+1

第1部分回报给我。 – karthikr 2013-05-09 21:23:25

+1

对我来说也是True,你在python3吗? – cmd 2013-05-09 21:23:58

+0

[在python3](http://ideone.com/F3BI7d) – Eric 2013-05-09 21:31:24

您必须循环访问错误的数据集;只是循环直接通过JSON加载字典里是没有必要要求.keys()第一:

data = json.loads(response) 
myList = [item for item in data if item == "number1"] 

您可能需要使用u"number1"避免Unicode和字节串间的转换:

data = json.loads(response) 
myList = [item for item in data if item == u"number1"] 

两个版本做工精细

>>> import json 
>>> data = json.loads('{"number1":"first", "number2":"second"}') 
>>> [item for item in data if item == "number1"] 
[u'number1'] 
>>> [item for item in data if item == u"number1"] 
[u'number1'] 

注意,在你的第一个例子,us不是一个UTF-8字符串;它是unicode数据,json库已经为你解码。另一方面,UTF-8字符串是编码字节的序列。您可能需要有关Unicode和Python阅读了理解上的差异:由Joel Spolsky的

在Python 2,你的期望是你的测试返回True将是cor矩形,你正在做别的错误:

>>> us = u'MyString' 
>>> us 
u'MyString' 
>>> type(us) 
<type 'unicode'> 
>>> us.encode('utf8') == 'MyString' 
True 
>>> type(us.encode('utf8')) 
<type 'str'> 

没有需要字符串编码成UTF-8进行比较;使用unicode文字来代替:

myComp = [elem for elem in json_data if elem == u"MyString"] 

3. us.encode('utf-8') == "MyString"返回False因为str.encode()功能是returning a bytes object

In [2]: us.encode('utf-8') 
Out[2]: b'MyString' 

在Python 3中,字符串是already Unicode,所以u'MyString'是多余的。

您正在尝试比较的Unicode代码点的字符串(u'MyString')字节('MyString')的字符串。这是一个“苹果和橘子”的比较。不幸的是,Python的2假装在某些情况下,这种比较是有效的,而不是总是返回False

>>> u'MyString' == 'MyString' # in my opinion should be False 
True 

这是给你的设计/开发者决定正确的比较应该是什么。这是一种可能的方式:

a = u'MyString' 
b = 'MyString' 
a.encode('UTF-8') == b # True 

我推荐的上面,而不是a == b.decode('UTF-8')因为所有u''风格字符串可以被编码与UTF-8字节,除了可能在一些奇怪的情况下,但不是所有的字节串可以这种方式解码为Unicode。

但是,如果您选择在比较之前对Unicode字符串进行UTF-8编码,那么在Windows系统上这样做会失败:u'Em dashes\u2014are cool'.encode('UTF-8') == 'Em dashes\x97are cool'。但是如果你.encode('Windows-1252')反而会成功。这就是为什么这是一个苹果和橙子的比较。

+1

为什么OP显然使用Python 2?如果是Python 2,他的测试会返回True,**而不是** False。 – 2013-05-09 21:39:29

+1

看起来我重复了他的错字。他在编辑之后明确指出了Python 2,所以我也会编辑我的答案。 – wberry 2013-05-09 21:42:52