У меня есть список кортежей, например.
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)
Это довольно прямолинейно. Но мне было интересно, есть ли какой-нибудь питонический способ сделать это?
Вы можете использовать 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')]
Вы можете создать 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')]
Вы также можете просто использовать метод сортировки списка 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)