2010-03-28 11 views
54

En Python 2.x, me podía pasar función personalizada para ordenados y .Sort funciones¿Cómo usar una función de comparación personalizada en Python 3?

>>> x=['kar','htar','har','ar'] 
>>> 
>>> sorted(x) 
['ar', 'har', 'htar', 'kar'] 
>>> 
>>> sorted(x,cmp=customsort) 
['kar', 'htar', 'har', 'ar'] 

Porque, en mi idioma, son consonents viene con este fin

"k","kh",....,"ht",..."h",...,"a" 

Pero En Python 3.x, parece que no pude pasar cmp palabra clave

¿Hay alguna alternativa o debo escribir mi propia función ordenada también?

Nota: simplifiqué usando "k", "kh", etc. Los caracteres reales son Unicodes y aún más complicado, a veces hay vocales antes y después de las consonantes, he hecho una función de comparación personalizada, Para que parte está bien. Solo el problema es que no pude pasar mi función de comparación personalizada a ordenada o .sort

+0

has necesitado simplemente 'ordenados (x)'? – SilentGhost

+0

@SilentGhost, para asegurarme, lo intenté de nuevo, por supuesto, no funcionaba, porque * mi * idioma original no está en la lista de configuración regional admitida por Operation Systems para hacer la clasificación. – YOU

+1

Puede envolver su cmp como una función clave. Busque en el sitio de clasificación de cmp_to_key. – Frank

Respuesta

22

utilizar el argumento key (y siguen el recipe sobre cómo convertir su antigua función cmp a una función key).

+0

+1, parece que la receta me da una solución, pero creo que voy a perder algo de rendimiento al pasar todos los operadores de comparación '< > =' a intermediarios, ya que mi clasificación personalizada original está escrita en C, tenía alrededor 1/2x velocidad de ordenación predeterminada. – YOU

+2

(Acabo de mirar su perfil) ¿Su empresa está bloqueando el acceso a Google y StackOverflow? ¿Qué tan estúpidos pueden ser? Pero sobre su respuesta: me interesaría la disminución del rendimiento real. ¿Puedes 'timeit'? –

+0

Sí, para bloquear a Google es que quieren que usemos goo.ne.jp (creo que su afiliado), pero personalizo NTLM Proxy y compilación de un script del lado del servidor en mi hosting y tunelización a través de eso. No sé por qué para stackoverflow. - Y claro, haré algunos puntos de referencia. – YOU

1

Utilice en su lugar el argumento key. Toma una función que toma el valor que se procesa y devuelve un valor único que proporciona la clave que se usará para ordenar.

sorted(x, key=somekeyfunc) 
+2

tecla solo acepta una función de parámetro, cmp tiene 2 parámetros, son comportamientos diferentes. y acabo de probar, obtuve el error, porque la palabra clave clave solo pasa un parámetro, 'TypeError: customsort() toma exactamente 2 argumentos posicionales (1 dado)' – YOU

+0

Eso es correcto. –

+0

Gracias por tomarse el tiempo para responder por cierto. – YOU

10

En lugar de un customsort(), necesita una función que traduzca cada palabra en algo que Python ya sepa cómo ordenar. Por ejemplo, podría traducir cada palabra a una lista de números donde cada número representa dónde aparece cada letra en su alfabeto. Algo como esto:

my_alphabet = ['a', 'b', 'c'] 

def custom_key(word): 
    numbers = [] 
    for letter in word: 
     numbers.append(my_alphabet.index(letter)) 
    return numbers 

x=['cbaba', 'ababa', 'bbaa'] 
x.sort(key=custom_key) 

Desde su idioma incluye cartas de varios caracteres, su función custom_key obviamente tendrá que ser más complicado. Sin embargo, eso debería darte la idea general.

+0

Gracias +1, esa es la manera ICU creo, pero desde * mi * idioma no tienen separadores de palabras y no tienen romanize estándar reglas, tomará tiempo para investigar, creo. – YOU

4

No sé si esto ayudará, pero puede consultar el módulo locale. Parece que puede establecer la configuración regional en su idioma y usar locale.strcoll para comparar cadenas utilizando las reglas de clasificación de su idioma.

+0

Eso es cierto para los idiomas populares, pero * mi * idioma no es totalmente compatible con Operation Systems, ICU y unicode.org, por lo que está fuera de duda, pero +1 para una buena sugerencia. – YOU

23

Usar la palabra clave key y functools.cmp_to_key para transformar su función de comparación:

sorted(x, key=functools.cmp_to_key(customsort)) 
+1

Debería decir ... key = functools.cmp_to_key (...) ... – yuzisee

+0

@yuzisee oops, gracias – aknuds1

Cuestiones relacionadas