2010-03-22 28 views
5

¿Cómo puedo eficiente y fácil ordenar una lista de tuplas sin ser sensible a caso?Ordenar una lista de tuplas sin mayúsculas y minúsculas

Por ejemplo esto:

[('a', 'c'), ('A', 'b'), ('a', 'a'), ('a', 5)] 

debería tener este aspecto una vez ordenados:

[('a', 5), ('a', 'a'), ('A', 'b'), ('a', 'c')] 

El tipo lexicográfico regulares pondrá 'A' antes de 'a' y producir lo siguiente:

[('A', 'b'), ('a', 5), ('a', 'a'), ('a', 'c')] 

Respuesta

10

puede utilizar key argumento sort 's para definir cómo desea considerar cada elemento con respecto a la clasificación:

def lower_if_possible(x): 
    try: 
     return x.lower() 
    except AttributeError: 
     return x 

L=[('a', 'c'), ('A', 'b'), ('a', 'a'), ('a', 5)] 

L.sort(key=lambda x: map(lower_if_possible,x)) 
print(L) 

Ver http://wiki.python.org/moin/HowTo/Sorting para una explicación de cómo utilizar key.

+0

fresco, que se tratando de descubrir cómo usar la tecla en esta situación y el uso de map() no se me ocurrió. ¡Gracias! –

0

Algo como esto debería funcionar:

def sort_ci(items): 
    def sort_tuple(tuple): 
     return ([lower(x) for x in tuple],) + tuple 
    temp = [sort_tuple(tuple) for tuple in items] 
    temp.sort() 
    return [tuple[1:] for tuple in temp] 

En otras palabras, crear una nueva lista, donde cada elemento es una tupla que consiste en el viejo tupla, con el prefijo con la misma tupla con cada elemento en minúsculas. Luego ordena eso.

Esto es un poco más rápido que usar sort 's argumento de función de comparación opcional, si su lista es larga.

2
list_of_tuples.sort(key=lambda t : tuple(s.lower() if isinstance(s,basestring) else s for s in t)) 
+0

Solución agradable y compacta. ¡Gracias! –

+0

Si sus tuplas pueden contener otras tuplas o estructuras de secuencia, entonces probablemente querrá la solución lower_if_possible, envuelto dentro de una persona que llama recursiva llama algo así como lower_sequence, que llama a sí mismo si encuentra un miembro que es en sí misma una secuencia. – PaulMcG

0

he aquí una solución que utiliza la idea decorador se ilustra en la sección "ordenado por llaves" de un artículo wiki Python (http://wiki.python.org/moin/HowTo/Sorting/).

# Create a list of new tuples whose first element is lowercase 
# version of the original tuple. I use an extra function to 
# handle tuples which contain non-strings. 
f = lambda x : x.lower() if type(x)==str else x 
deco = [(tuple(f(e) for e in t), t) for t in ex] 

# now we can directly sort deco and get the result we want 
deco.sort() 

# extract the original tuples in the case-insensitive sorted order 
out = [t for _,t in deco] 
0

Una versión simplificada de Paul McGuires funciona:

list_of_tuples.sort(key=lambda t : tuple(t[0].lower())) 

(donde T [0] referencias que elemento de la tupla que desea utilizar, en este caso el primero)

Cuestiones relacionadas