我正在尝试使用比较字符串对象的列表解析,但其中一个字符串是utf-8,它是json.loads的副产品。情形:
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的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"]
答案 0 :(得分:21)
你必须循环错误的数据集;只需直接在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以了解其中的区别:
在Python 2上,你期望你的测试返回True
是正确的,你做错了其他事情:
>>> 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"]
答案 1 :(得分:12)
您正在尝试将字符串('MyString'
)与一串Unicode代码点(u'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')
取而代之,它就会成功。这就是为什么它是苹果和橘子的比较。
答案 2 :(得分:3)
我假设你正在使用Python 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'
是多余的。