Сортировать список кортежей на основе другого списка

1

У меня есть список кортежей, например.

l1 = [(1, 'a', 'x'), (2, 'b', 'y'), (3, 'a', 'z'), (4, 'c', 'xyz')]

У меня есть другой список

l2 = ['a', 'b', 'c']

Я хочу сортировать l1 по второму значению каждого кортежа в соответствии с порядком, представленным в l2. Конечный результат должен быть

l1 = [(1, 'a', 'x'), (3, 'a', 'z'), (2, 'b', 'y'), (4, 'c', 'xyz')]

Как вы можете видеть, кортежи, второе значение которых было a, присутствуют первыми, затем появляются кортежи со вторым значением b и, наконец, те, которые имеют c.

Я написал следующее:

l = []
for i in l2:
    for j in l1:
        if i == j(1):
        l.append(j)

Это довольно прямолинейно. Но мне было интересно, есть ли какой-нибудь питонический способ сделать это?

Теги:

3 ответа

2

Вы можете использовать sorted с соответствующей key функцией:

l1 = [(1, 'a', 'x'), (2, 'b', 'y'), (3, 'a', 'z'), (4, 'c', 'xyz')]
l2 = ['a', 'b', 'c']
d2 = {v: i for i, v in enumerate(l2)}  # map elements to indexes
# {'a': 0, 'b': 1, 'c': 2}

sorted(l1, key=lambda x: d2[x[1]])
# [(1, 'a', 'x'), (3, 'a', 'z'), (2, 'b', 'y'), (4, 'c', 'xyz')]
0

Вы можете создать dict который использует значение как ключ, и индекс, заданный enumerate(l2) сортирует его:

l1 = [(1, 'a', 'x'), (2, 'b', 'y'), (3, 'a', 'z'), (4, 'c', 'xyz')]
l2 = ['a', 'b', 'c']

sorting ={key:idx for idx,key in enumerate(l2)}

l3 = sorted(l1, key = lambda x: sorting.get(x[1],9999999999))

print(l3)

Использование dict таким образом имеет то преимущество, что не использует index(...) для каждого поиска в l2.

Вы должны использовать dict.get() чтобы избежать пропущенных ключей, вызывающих проблемы, и просто предоставить значение по умолчанию, которое не должно быть в списке, чтобы они попадали в конец/фронт.

Выход:

[(1, 'a', 'x'), (3, 'a', 'z'), (2, 'b', 'y'), (4, 'c', 'xyz')]
-1

Вы также можете просто использовать метод сортировки списка l1 для сортировки по второму значению каждого кортежа:

l1 = [(1, 'a', 'x'), (2, 'b', 'y'), (3, 'a', 'z'), (4, 'c', 'xyz')]

l1.sort(key=lambda x: x[1])

print(l1)

Если этого недостаточно, и вам нужен второй список l2 для определения порядка, вы можете использовать индексный метод в списке:

l1 = [(1, 'a', 'x'), (2, 'b', 'y'), (3, 'a', 'z'), (4, 'c', 'xyz')]
l2 = ['a', 'b', 'c']

l1.sort(key=lambda x: l2.index(x[1]))

print(l1)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню