如何将 unicode 类型与 python 中的字符串进行比较?
Posted
技术标签:
【中文标题】如何将 unicode 类型与 python 中的字符串进行比较?【英文标题】:How can I compare a unicode type to a string in python? 【发布时间】:2013-05-04 11:50:01 【问题描述】:我正在尝试使用比较字符串对象的列表理解,但其中一个字符串是 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"]
【问题讨论】:
第 1 部分对我来说是真实的。 对我来说也返回 True,你在 python3 中吗? In python3 您在寻找us.decode('utf-8')
吗? json 不为您处理 unicode 解析吗?你想做什么?
我将添加更完整的代码以准确显示正在发生的事情。
【参考方案1】:
你一定是在循环错误的数据集;直接循环遍历 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 以了解其中的区别:
The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!) 乔尔·斯波尔斯基
Python Unicode HOWTO
Pragmatic Unicode by Ned Batchelder
在 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"]
【讨论】:
【参考方案2】:您正在尝试将一串字节 ('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')
,它就会成功。这就是为什么它是一个苹果和橘子的比较。
【讨论】:
为什么 OP 使用 Python 2 很明显?如果是 Python 2,他的测试将返回True
,not False
。
看来我把他的错字重复给他了。他在编辑后明确声明了 Python 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'
是多余的。
【讨论】:
以上是关于如何将 unicode 类型与 python 中的字符串进行比较?的主要内容,如果未能解决你的问题,请参考以下文章