Как отсортировать список по другому списку?

Есть список:

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

другой список:

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

Я хочу сортировать по b:

sort_it(a, b)

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

Как это сделать?

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

Это сортирует a на месте, используя индекс в b первого элемента каждого набора из a в качестве значений, которые он сортирует.

Другой, возможно, более чистый способ записи:

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

Если у вас было большое количество элементов, было бы более эффективно делать что-то по-другому, потому что .index() может быть дорогостоящей операцией в длинном списке, и вам действительно не нужно делать полную сортировку с тех пор вы уже знаете порядок:

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

Обратите внимание, что это будет работать только для списка из 2-х кортежей. Если вы хотите, чтобы он работал для кортежей произвольной длины, вам нужно немного его изменить:

mapping = dict((x[0], x[1:]) for x in a)
a[:] = [(x,) + mapping[x] for x in b]
58
ответ дан 10 окт. '12 в 11:04
источник

Другая возможность - сортировать a, сортировать индексы b в соответствии с b и сортировать a в соответствии с индексами

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

поскольку каждая сортировка принимает n * log (n), она все еще масштабируется для больших списков

1
ответ дан 24 апр. '16 в 22:54
источник

Традиционная сортировка может не понадобиться.

[tup for lbl in b for tup in a if tup[0] == lbl]
# [('ec', 3), ('ax', 1), ('bk', 5)]
1
ответ дан 29 сент. '17 в 9:51
источник