2012-10-10 36 views
28

hay una lista:¿Cómo ordenar una lista según otra lista?

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

otra lista:

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

que desea ordenar un acuerdo con b:

sort_it(a, b) 

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

cómo hacer esto?

+2

posible duplicado de [lista de clasificación basada en los valores de otra lista?] (Http://stackoverflow.com/questions/6618515/sorting-list-based-on-values-from-another-list) – user1251007

Respuesta

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

Esto ordena a en el lugar usando el índice en b del primer elemento de cada tupla de a como los valores que ordena en.

Otro, posiblemente, más limpio, forma de escribir sería:

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

Si tuviera un gran número de artículos, que podría ser más eficiente de hacer las cosas un poco diferente, porque .index() puede haber una operación costosa en una larga lista, y que en realidad no tiene que hacer una clasificación completa puesto que ya conoce el orden:

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

Tenga en cuenta que esto sólo funcionará para una lista de 2-tuplas Si quieres que funcione para tuplas de longitud arbitraria, que había necesidad de modificarlo ligeramente:

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

Otra posibilidad es ordenar a, ordenar los índices de b acuerdo con b y de ordenar la a según los índices

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])] 

ya que cada clasificación se lleva a n * log (n) esto sigue siendo escalable para las listas más grandes

0

puede no ser necesario clasificación tradicional.

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