Python UTF-8 Comparación
-
25-09-2019 - |
Pregunta
a = {"a":"çö"}
b = "çö"
a['a']
>>> '\xc3\xa7\xc3\xb6'
b.decode('utf-8') == a['a']
>>> False
¿Qué está pasando ahí?
edit = Lo siento, fue mi error. Todavía es falso. Estoy usando Python 2.6 en Ubuntu 10.04.
Solución
Posibles soluciones
Cualquiera de escribir así:
a = {"a": u"çö"}
b = "çö"
b.decode('utf-8') == a['a']
O como este (también se puede omitir la .decode('utf-8')
en ambos lados):
a = {"a": "çö"}
b = "çö"
b.decode('utf-8') == a['a'].decode('utf-8')
O como este (mi recomendación):
a = {"a": u"çö"}
b = u"çö"
b == a['a']
Explicación
actualiza basándose en el comentario de Tim En el código original b.decode('utf-8') == u'çö'
y a['a'] == 'çö'
, por lo que en realidad está haciendo la siguiente comparación:.
u'çö' == 'çö'
Uno de los objetos es de tipo unicode
, el otro es de tipo str
, por lo que con el fin de ejecutar la comparación, el str
se convierte en unicode
y luego se comparan los dos objetos unicode
. Funciona bien en el caso de las cadenas puramente ASCII, por ejemplo:. u'a' == 'a'
, ya unicode('a') == u'a'
Sin embargo, se produce un error en el caso de u'çö' == 'çö'
, ya que los rendimientos unicode('çö')
el siguiente error: UnicodeDecodeError: 'ascii' codec no puede decodificar bytes 0xC3 en la posición 0: No ordinales de rango (128) , y por lo tanto el conjunto de los rendimientos de comparación falsas y las cuestiones de la siguiente advertencia: UnicodeWarning: Unicode fallaron igual comparación para convertir ambos argumentos a Unicode - interpretarlos como siendo desigual
Otros consejos
b
es un string
, a
es un dict
¿Quieres (creo):
b == a['a']
UTF-8 es una codificación que se utiliza para grabar en archivos de texto Unicode. Sin embargo, en Python se trabaja con objetos que tienen una forma fija para representar texto Unicode, y de esa manera no es UTF-8.
Usted todavía puede comparar cadenas Unicode en Python, pero esto no está relacionado con UTF-8, excepto que si usted quiere poner constantes en estas cadenas Unicode, entonces necesitará para codificar el texto del archivo que contiene el código fuente, en UTF-8. Tan pronto como se ejecuta el operador de asignación, la cadena ya no es UTF-8, pero ahora es la representación interna de Python.
Por cierto, si usted está haciendo comparaciones con Unicode, es probable que desee utilizar el módulo unicodedata y normalizar las cuerdas antes de que se hacen las comparaciones.
Trate b == un [ 'a']
que está comparando una cadena a un dict.
>>> a = {"a":"çö"}
>>> b = "çö"
>>> a == b
False
>>> a['a'] == b
True
Si se compara la cadena (b) al miembro de un (una [ 'a']), entonces se obtiene el resultado deseado.
Asegúrese de que el código está en UTF-8 (NO Latin-1) y / o utilizar una línea de codificación como así:
#! /usr/bin/python
# -*- coding: utf-8 -*-
a = {"a": u"çö"}
b = "çö"
assert b == a['a']
assert b.decode('utf-8') == a['a'].decode('utf-8')
Si utiliza Unicode en todos los ámbitos, puede importar unicode_literals desde el futuro y reduzcan al máximo las angustias codificación:
#! /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')
Si un utiliza el archivo unicode_literals, todas las "cadenas" son ahora u objetos "Unicode" (por la codificación del archivo) si no están b "antepuesto" con AB (para emular la cadena / bytes dividida en Python 3 .X).
NullUserException es justo que este debe ser correcta:
b == a['a']
Usted todavía está recibiendo "falso" porque estás decodificación de un lado como UTF-8 (la creación de una cadena Unicode), mientras que el otro lado sigue siendo una cadena de bytes codificados UTF-8.