Oswaldo Hernández escribió:
Sio2 escribió:
Estoy intentando ordenar una serie de nombres alfabéticamente, pero hago
algo mal o esta función no me va.

Veamos:
$ python
Python 2.5.4 (r254:67916, Nov 19 2009, 22:14:20)
[GCC 4.3.4] on linux2
Type "help", "copyright", "credits" or "license" for more information.
import locale
locale.setlocale(locale.LC_ALL,'')
'es...@euro'
a="Diaz Flor, M"
b="Diaz Flores, M"


Como veis no pongo ni los acentos para poder usar cmp:

cmp(a,b)
-1

Lo esperable, "a" va antes que "b". Sin embargo:

locale.strcoll(a,b)
8

"b" antes que "a" y, como consecuencia, el listado no sale ordenado
correctamente.

¿Se me escapa algo? ¿No funciona bien strcoll?

(Con es_ES.UTF-8 me sucede exactamente lo mismo)


El ordenamiento con las funciones de locale es muy distinto al ordenamiento ascii habitual. Cada texto se evalúa en función de reglas de peso en donde los espacios, y otros caracteres apenas pesan.

Esto hace que a veces lo veamos de forma extraña, pero tiene su lógica y sus ventajas.

Ejemplos:

 >>> locale.strcoll("'''Miguel'''", "Alberto")
12

 >>> locale.strcoll("      Juan", "Adrian")
9

En el caso que muestras strcoll practicamente lo que está haciendo es comparar "DiazFlorM" con "DiazFloresM", omitiendo (o casi) los espacios y las comas ya que su peso es ínfimo.

En una base de datos que utilice el locale para ordenar veras que el comportamiento es similar.

(PostgreSQL 8.3)

select 'Diaz, M'
union
select 'Diaz Flor, M'
union
select 'Diaz Flores, M'
order by 1 asc;


    ?column?
----------------
 Diaz Flor, M
 Diaz Flores, M
 Diaz, M
(3 filas)


En este ejemplo la ordenación no es la que pretendía, pero sirve para ilustrar el como funciona LC_COLLATE ;)

La consulta esta hecha el una base de datos instalada en windows con lc_collate establecido a:

postgres=# show lc_collate;
     lc_collate
--------------------
 Spanish_Spain.1252
(1 fila)

Si embargo si repito lo mismo en otra base de datos instalada en linux con LC_COLLATE:

postgres=# show lc_collate;
 lc_collate
-------------
 es_ES.UTF-8
(1 fila)

postgres=# select 'Diaz, M' union select 'Diaz Flor, M' union select 'Diaz Flores, M' order by 1 asc;
    ?column?
----------------
 Diaz Flores, M
 Diaz Flor, M
 Diaz, M
(3 filas)


Saludos,


--
*****************************************
Oswaldo Hernández
oswaldo (@) soft-com (.) es
*****************************************
PD:
Antes de imprimir este mensaje, asegúrese de que es necesario.
El medio ambiente está en nuestra mano.
_______________________________________________
Python-es mailing list
Python-es@python.org
http://mail.python.org/mailman/listinfo/python-es
FAQ: http://python-es-faq.wikidot.com/

Responder a