2010-03-22 9 views
5

Jak można skutecznie i łatwo uporządkować listę krotek bez jest wrażliwy na sprawy?Sortowanie listy krotek bez czułości przypadku

Na przykład w ten sposób:

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

powinien wyglądać ten jeden raz sortowane:

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

Regularne leksykograficzny rodzaj położy 'A' przed 'A' i dają to:

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

Odpowiedz

10

można użyć key argumentu sort „s, aby określić, jak chcesz traktować każdy element w odniesieniu do sortowania:

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) 

Zobacz http://wiki.python.org/moin/HowTo/Sorting o wyjaśnienie, jak używać key.

+0

chłodny, ja próbuje dowiedzieć się, jak używać klucza w tej sytuacji i przy użyciu mapy() nie przyszło mi do głowy. Dzięki! –

0

Coś jak to powinno działać:

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] 

Innymi słowy, należy utworzyć nową listę, w której każdy element jest krotka składająca starej krotki, z prefiksem o tej samej krotki z każdej pozycji małymi literami. Następnie uporządkować to.

Jest to nieco szybsze niż użycie opcjonalnego argumentu funkcji porównywania sort, jeśli twoja lista jest długa.

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

Nicea, kompaktowe rozwiązanie. Dzięki! –

+0

Jeśli krotki mogą zawierać inne krotki lub struktury sekwencji, to pewnie chcesz lower_if_possible rozwiązanie, owinięte w rekurencyjnego rozmówcy nazywa coś podobnego lower_sequence, który nazywa się, jeżeli stwierdzi, że jest członkiem sama sekwencja. – PaulMcG

0

Oto rozwiązanie, które wykorzystuje ideę dekorator przedstawione w części „klasyfikowane według kluczy” w artykule Python wiki (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

Uproszczona wersja Paul Mcguires działa:

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

(gdzie t [0] referencje który krotka elementu, który chcesz użyć, w tym przypadku pierwsze)