34

文字列オブジェクトを比較するリスト内包表記を使用しようとしていますが、文字列の 1 つが json.loads の副産物である utf-8 です。シナリオ:

us = u'MyString' # is the utf-8 string

私の質問のパート 1 は、なぜこれが False を返すのですか? :

us.encode('utf-8') == "MyString" ## False

パート 2 - リスト内包表記内で比較するにはどうすればよいですか?

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"]
4

3 に答える 3

12

'MyString'バイト文字列 ( ) と Unicode コード ポイント ( )の文字列を比較しようとしていますu'MyString'。これは「リンゴとオレンジ」の比較です。残念ながら、Python 2 は場合によっては、常に を返すのではなく、この比較が有効であるかのように装いますFalse

>>> u'MyString' == 'MyString'  # in my opinion should be False
True

正しい比較を決定するのは、設計者/開発者としてのあなた次第です。考えられる方法の 1 つを次に示します。

a = u'MyString'
b = 'MyString'
a.encode('UTF-8') == b  # True

奇妙なケースを除いて、a == b.decode('UTF-8')すべてのスタイル文字列を UTF-8 でバイトにエンコードできますが、すべてのバイト文字列をそのように Unicode にデコードできるわけではないため、代わりに上記をお勧めします。u''

しかし、比較する前に Unicode 文字列の UTF-8 エンコードを行うことを選択した場合、Windows システムでは次のように失敗しますu'Em dashes\u2014are cool'.encode('UTF-8') == 'Em dashes\x97are cool'。しかし、.encode('Windows-1252')代わりにそれが成功する場合。というわけで、リンゴとミカンの比較です。

于 2013-05-09T21:34:28.233 に答える
3

Python 3 を使用していると仮定しています。関数がバイト オブジェクトus.encode('utf-8') == "MyString"を返しFalseているため、戻り値は次のとおりです。str.encode()

In [2]: us.encode('utf-8')
Out[2]: b'MyString'

Python 3 では、文字列は既に Unicodeであるため、u'MyString'は不要です。

于 2013-05-09T21:27:46.573 に答える