web-dev-qa-db-fra.com

Comment trier une liste en fonction d'une autre liste?

Il y a une liste:

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

une autre liste: 

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

Je veux trier un selon b:

sort_it(a, b)

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

Comment faire ça?

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

Ceci trie a sur place en utilisant l'index dans b du premier élément de chaque Tuple de a comme les valeurs sur lesquelles il est trié.

Une autre façon d’écrire ce serait peut-être:

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

Si vous avez un grand nombre d'éléments, il serait peut-être plus efficace de faire les choses un peu différemment, car .index() peut être une opération coûteuse sur une longue liste, et vous n'avez pas réellement besoin de faire un tri complet puisque vous connaissez déjà la commande. :

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

Notez que cela ne fonctionnera que pour une liste de 2 tuples. Si vous voulez que cela fonctionne pour des n-uplets de longueur arbitraire, vous devrez le modifier légèrement:

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

Une autre possibilité consiste à trier a, à trier les indices de b en fonction de b et à trier le a en fonction des

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

puisque chaque tri prend n * log (n), cela reste évolutif pour de plus grandes listes

1
fritz-johann

Le tri traditionnel peut ne pas être nécessaire.

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