如何将 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,他的测试将返回 Truenot 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 中的字符串进行比较?的主要内容,如果未能解决你的问题,请参考以下文章

Django之Form组件与验证规则

Python 2.7:如何将字符串中的 unicode 转义转换为实际的 utf-8 字符

python字符编码与解码 unicode,str

了解bytesstr与unicode的区别

python编码类型互转总结

在 Python 3.0 中,标准库中的所有内容都会将字符串视为 unicode 吗?