2012-10-10 13 views
28

Istnieje lista:Jak sortować listę według innej listy?

a = [("ax", 1), ("ec",3), ("bk", 5)] 

kolejna lista:

b = ["ec", "ax", "bk"] 

chcę sortować według b:

sort_it(a, b) 

a = [("ec",3), ("ax", 1), ("bk", 5)] 

Jak to zrobić?

+2

możliwe duplikat [sortowanie listy w oparciu o wartości z innej listy?] (Http://stackoverflow.com/questions/6618515/sorting-list-based-on-values-from-another-list) – user1251007

Odpowiedz

47
a.sort(key=lambda x: b.index(x[0])) 

to sortuje a w miejscu za pomocą indeksu w b pierwszego elementu każdej krotki a jako wartości sortuje dalej.

innego, ewentualnie czystsze, sposób pisania byłoby:

a.sort(key=lambda (x,y): b.index(x)) 

Jeśli miał dużą liczbę elementów, to może być bardziej efektywne, aby robić rzeczy nieco inaczej, ponieważ .index() może być kosztowna operacja na długiej liście, a nie faktycznie trzeba zrobić pełną sortowania skoro już wiesz kolejność:

mapping = dict(a) 
a[:] = [(x,mapping[x]) for x in b] 

Zauważ, że to będzie działać tylko dla lista 2-krotnych. Jeśli chcesz go do pracy na krotki arbitralne długości, trzeba by go zmodyfikować nieco:

mapping = dict((x[0], x[1:]) for x in a) 
a[:] = [(x,) + mapping[x] for x in b] 
1

Innym posibility jest posortowanie a, sortowania wskaźników b według b i niż sortować według a indeksy

a.sort(key=lambda x: x[0]) 
ind = [i[0] for i in sorted(enumerate(b),key=lambda x: x[1])] 
a = [i[0] for i in sorted(zip(a,ind),key=lambda x: x[1])] 

ponieważ każdy sortowania odbywa n * log (n) to wciąż skalowalna dla większych list

0

tradycyjny sortowania nie mogą być potrzebne.

[tup for lbl in b for tup in a if tup[0] == lbl] 
# [('ec', 3), ('ax', 1), ('bk', 5)] 
Powiązane problemy