xf1 escape error python unicode locale

escape - Python no está ordenando unicode correctamente. Strcoll no ayuda



unicode escape python (6)

@gnibbler, usar PyICU con la función sorted () funciona en un entorno Python3. Después de investigar un poco la documentación de la API de ICU y algunos experimentos, encontré la función getSortKey () :

import PyICU collator = PyICU.Collator.createInstance(PyICU.Locale(''de_DE.UTF-8'')) sorted([''a'',''b'',''c'',''ä''],key=collator.getSortKey)

que produce la colación deseada:

[''a'', ''ä'', ''b'', ''c'']

en lugar de la colación no deseada:

sorted([''a'',''b'',''c'',''ä'']) [''a'', ''b'', ''c'', ''ä'']

Tengo un problema con la clasificación de listas utilizando la intercalación de Unicode en Python 2.5.1 y 2.6.5 en OSX, así como en Linux.

import locale locale.setlocale(locale.LC_ALL, ''pl_PL.UTF-8'') print [i for i in sorted([u''a'', u''z'', u''ą''], cmp=locale.strcoll)]

Que debe imprimir:

[u''a'', u''ą'', u''z'']

Pero en cambio imprime:

[u''a'', u''z'', u''ą'']

Resumiendo, parece como si se hubiera roto el strcoll. Lo probé con varios tipos de variables (cadenas codificadas no Unicode).

¿Qué hago mal?

Saludos cordiales, Tomasz Kopczuk.


Aparentemente, la única manera de que la clasificación funcione en todas las plataformas es utilizar la biblioteca ICU con enlaces PyICU ( PyICU en PyPI ).

En OS X: sudo port install py26-pyicu , el error de sudo port install py26-pyicu descrito aquí: https://svn.macports.org/ticket/23429 (oh, la alegría de usar macports).

Lamentablemente, la documentación de PyICUs es muy deficiente, pero logré averiguar cómo se hace:

import PyICU collator = PyICU.Collator.createInstance(PyICU.Locale(''pl_PL.UTF-8'')) print [i for i in sorted([u''a'', u''z'', u''ą''], cmp=collator.compare)]

lo que da:

[u''a'', u''ą'', u''z'']

Otro pro - @bobince: es seguro para la ejecución de subprocesos, por lo que no es inútil cuando se configuran entornos locales de solicitud.


Aquí es cómo me las arreglé para ordenar el idioma persa correctamente (sin PyICU) (usando Python 3.x):

Primero establezca la configuración regional (no olvide importar la configuración regional y la plataforma )

if platform.system() == ''Linux'': locale.setlocale(locale.LC_ALL, ''fa_IR.UTF-8'') elif platform.system() == ''Windows'': locale.setlocale(locale.LC_ALL, ''Persian_Iran.1256'') else: pass (or any other OS)

Luego ordénalo usando la clave:

a = [''ا'',''ب'',''پ'',''ت'',''ث'',''ج'',''چ'',''ح'',''خ'',''د'',''ذ'',''ر'',''ز'',''ژ'',''س'',''ش'',''ص'',''ض'',''ط'',''ظ'',''ع'',''غ'',''ف'',''ق'',''ک'',''گ'',''ل'',''م'',''ن'',''و'',''ه'',''ي''] print(sorted(a,key=locale.strxfrm))

Para lista de objetos:

a = [{''id'':"ا"},{''id'':"ب"},{''id'':"پ"},{''id'':"ت"},{''id'':"ث"},{''id'':"ج"},{''id'':"چ"},{''id'':"ح"},{''id'':"خ"},{''id'':"د"},{''id'':"ذ"},{''id'':"ر"},{''id'':"ز"},{''id'':"ژ"},{''id'':"س"},{''id'':"ش"},{''id'':"ص"},{''id'':"ض"},{''id'':"ط"},{''id'':"ظ"},{''id'':"ع"},{''id'':"غ"},{''id'':"ف"},{''id'':"ق"},{''id'':"ک"},{''id'':"گ"},{''id'':"ل"},{''id'':"م"},{''id'':"ن"},{''id'':"و"},{''id'':"ه"},{''id'':"ي"}] print(sorted(a, key=lambda x: locale.strxfrm(x[''id'']))

Finalmente puedes devolver el local:

locale.setlocale(locale.LC_ALL, '''')


En ubuntu lucid, la ordenación con cmp parece funcionar bien, pero mi codificación de salida es incorrecta.

>>> import locale >>> locale.setlocale(locale.LC_ALL, ''pl_PL.UTF-8'') ''pl_PL.UTF-8'' >>> print [i for i in sorted([u''a'', u''z'', u''ą''], cmp=locale.strcoll)] [u''a'', u''/u0105'', u''z'']

Usar la tecla con locale.strxfrm no funciona a menos que me esté faltando algo

>>> print [i for i in sorted([u''a'', u''z'', u''ą''], key=locale.strxfrm)] Traceback (most recent call last): File "<stdin>", line 1, in <module> UnicodeEncodeError: ''ascii'' codec can''t encode character u''/u0105'' in position 0: ordinal not in range(128)


Solo para agregar a la investigación de tkopczuk: Este es definitivamente un error de gcc, al menos para la versión 4.2.1 en OS X 10.6.4. Puede reproducirse llamando a C strcoll() directamente como en este fragmento .

EDITAR: Aún en el mismo sistema, encuentro que para las versiones UTF-8 de de_DE, fr_FR, pl_PL, el problema está ahí, pero para las versiones ISO-88591 de fr_FR y de_DE, el orden es correcto. Desafortunadamente para el OP, ISO-88592 pl_PL también tiene errores:

The order for Polish ISO-8859 is: LATIN SMALL LETTER A LATIN SMALL LETTER Z LATIN SMALL LETTER A WITH OGONEK The LC_COLLATE culture and encoding settings were pl_PL, ISO8859-2. The order for Polish Unicode is: LATIN SMALL LETTER A LATIN SMALL LETTER Z LATIN SMALL LETTER A WITH OGONEK The LC_COLLATE culture and encoding settings were pl_PL, UTF8. The order for German Unicode is: LATIN SMALL LETTER A LATIN SMALL LETTER Z LATIN SMALL LETTER A WITH DIAERESIS The LC_COLLATE culture and encoding settings were de_DE, UTF8. The order for German ISO-8859 is: LATIN SMALL LETTER A LATIN SMALL LETTER A WITH DIAERESIS LATIN SMALL LETTER Z The LC_COLLATE culture and encoding settings were de_DE, ISO8859-1. The order for Fremch ISO-8859 is: LATIN SMALL LETTER A LATIN SMALL LETTER E WITH ACUTE LATIN SMALL LETTER Z The LC_COLLATE culture and encoding settings were fr_FR, ISO8859-1. The order for French Unicode is: LATIN SMALL LETTER A LATIN SMALL LETTER Z LATIN SMALL LETTER E WITH ACUTE The LC_COLLATE culture and encoding settings were fr_FR, UTF8.