web-dev-qa-db-ja.com

Python UTF-8の比較

a = {"a":"çö"}
b = "çö"
a['a']
>>> '\xc3\xa7\xc3\xb6'

b.decode('utf-8') == a['a']
>>> False

何が起こっているのですか?

edit =すみません、それは私の間違いでした。それはまだ誤りです。 Ubuntu10.04でPython 2.6を使用しています。

18
erkangur

可能な解決策

次のように記述します。

_a = {"a": u"çö"}
b = "çö"
b.decode('utf-8') == a['a']
_

またはこのように(両側の.decode('utf-8')をスキップすることもできます):

_a = {"a": "çö"}
b = "çö"
b.decode('utf-8') == a['a'].decode('utf-8')
_

またはこのように(私の推奨):

_a = {"a": u"çö"}
b = u"çö"
b == a['a']
_

説明

Timのコメントに基づいて更新されました。元のコードでは、b.decode('utf-8') == u'çö'と_a['a'] == 'çö'_なので、実際には次の比較を行っています。

_u'çö' == 'çö'
_

オブジェクトの1つはタイプunicodeで、もう1つはタイプstrであるため、比較を実行するために、strunicodeに変換されます。次に、2つのunicodeオブジェクトが比較されます。純粋にASCII文字列の場合、たとえば、unicode('a') == u'a'なので、_u'a' == 'a'_の場合は正常に機能します。

ただし、unicode('çö')は次のエラーを返すため、_u'çö' == 'çö'_の場合は失敗します。nicodeDecodeError: 'ascii'コーデックは位置0のバイト0xc3をデコードできません:序数が範囲内にありません(128)したがって、比較全体がFalseを返し、次の警告を発行します。nicodeWarning:Unicodeの等しい比較は両方の引数をUnicodeに変換できませんでした-それらを等しくないと解釈します

29
Bolo

bstringadictです

あなたが欲しい(私は信じています):

b == a['a']

5

UTF-8は、Unicodeテキストをファイルに記録するために使用されるエンコーディングです。ただし、Pythonでは、Unicodeテキストを表す固定された方法を持つオブジェクトを操作しており、その方法はUTF-8ではありません。

PythonでもUnicode文字列を比較できますが、これはUTF-8とは関係ありません。ただし、これらのUnicode文字列に定数を挿入する場合は、ソースコードを含むファイルのテキストをUTF-でエンコードする必要があります。 8.8。代入演算子が実行されるとすぐに、文字列はUTF-8ではなくなり、Python内部表現になります。

ちなみに、Unicodeと比較する場合は、unicodedataモジュールを使用して、比較を行う前に文字列を正規化することをお勧めします。

3
Michael Dillon

文字列をdictと比較しています。

>>> a = {"a":"çö"}
>>> b = "çö"
>>> a == b
False
>>> a['a'] == b
True

文字列(b)を(a ['a'])のメンバーと比較すると、目的の結果が得られます。

2
brennie

B == a ['a']を試してください

2
PaulMcG

NullUserExceptionは正しいので、これは正しいはずです。

b == a['a']

一方をutf-8(Unicode文字列を作成)としてデコードし、もう一方をutf-8でエンコードされたバイト文字列のままにするため、「False」が発生します。

0
chryss

コードがUTF-8(Latin-1ではない)であることを確認するか、次のようにコーディング行を使用してください。

#! /usr/bin/python
# -*- coding: utf-8 -*-
a = {"a": u"çö"}
b = "çö"
assert b == a['a']
assert b.decode('utf-8') == a['a'].decode('utf-8')

全面的にUnicodeを使用している場合は、将来からunicode_literalsをインポートして、エンコードの問題を減らすことができます。

#! /usr/bin/python
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
a = {"a": u"çö"}
b = "çö"
assert b == a['a']
assert b == a['a']
assert b.encode('utf-8') != a['a']
assert b.encode('utf-8') == a['a'].encode('utf-8')

ファイルがunicode_literalsを使用している場合、すべての「文字列」は、abがb「先頭」にない場合(ファイルのコーディングごとに)u「unicode」オブジェクトになります(Python 3.X)。

0
Jason Scheirer