如何将unicode类型与python中的字符串进行比较?

rGi*_*Gil 34 python unicode list-comprehension python-2.7

我试图使用比较字符串对象的列表理解,但其中一个字符串是utf-8,json.loads的副产品.场景:

us = u'MyString' # is the utf-8 string
Run Code Online (Sandbox Code Playgroud)

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

us.encode('utf-8') == "MyString" ## False
Run Code Online (Sandbox Code Playgroud)

第二部分 - 如何在列表理解中进行比较?

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

编辑:我正在使用使用Python 2.7的Google App Engine

这是一个更完整的问题示例:

#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"]
Run Code Online (Sandbox Code Playgroud)

Mar*_*ers 21

你必须循环错误的数据集; 只需直接在JSON加载的字典上循环,就不需要先调用.keys():

data = json.loads(response)
myList = [item for item in data if item == "number1"]  
Run Code Online (Sandbox Code Playgroud)

您可能希望使用u"number1"以避免Unicode和字节字符串之间的隐式转换:

data = json.loads(response)
myList = [item for item in data if item == u"number1"]  
Run Code Online (Sandbox Code Playgroud)

两个版本都运行良好:

>>> 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']
Run Code Online (Sandbox Code Playgroud)

请注意,在你的第一个例子,us不是一个UTF-8串; 它是unicode数据,json库已经为你解码了.另一方面,UTF-8字符串是序列编码的字节.您可能希望阅读Unicode和Python以了解其中的差异:

在Python 2上,您对测试返回的True期望是正确的,您正在做其他错误:

>>> us = u'MyString'
>>> us
u'MyString'
>>> type(us)
<type 'unicode'>
>>> us.encode('utf8') == 'MyString'
True
>>> type(us.encode('utf8'))
<type 'str'>
Run Code Online (Sandbox Code Playgroud)

没有必要将字符串编码成UTF-8进行比较; 改为使用unicode文字:

myComp = [elem for elem in json_data if elem == u"MyString"]
Run Code Online (Sandbox Code Playgroud)


wbe*_*rry 12

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

>>> u'MyString' == 'MyString'  # in my opinion should be False
True
Run Code Online (Sandbox Code Playgroud)

作为设计师/开发人员,您可以自行决定正确的比较.这是一种可能的方式:

a = u'MyString'
b = 'MyString'
a.encode('UTF-8') == b  # True
Run Code Online (Sandbox Code Playgroud)

我建议使用上面的代码而不是a == b.decode('UTF-8')因为所有u''样式字符串都可以用UTF-8编码成字节,除非可能在某些奇怪的情况下,但并非所有字节字符串都可以通过这种方式解码为Unicode.

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