【问题标题】:How can I compare a unicode type to a string in python?如何将 unicode 类型与 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 中吗?
  • 您在寻找us.decode('utf-8')吗? json 不为您处理 unicode 解析吗?你想做什么?
  • 我将添加更完整的代码以准确显示正在发生的事情。

标签: python unicode python-2.7 list-comprehension


【解决方案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 以了解其中的区别:

在 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' 是多余的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-29
      • 2020-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多