Сортировать кортеж по значению используйте список, когда значение равно
У меня есть список:
test1 = ["a","b","c","d","e","f","g","h","i"]
И список кортежей:
test2 = [("c",1),("g",1),("b",1),("e",1),("g",1),("d",10),("a",10)]
Мне нужно отсортировать:
[val for (key, val) in test2]
и когда val
равно одинаков val
отсортировано по test1
:
test3 = [("b",1),("c",1),("e",1),("f",1),("g",1),("a",10),("d",10)]
2 ответа
Решение
sorted
принимает необязательный параметр key
, Возвращаемое значение функции (каждый элемент передается функции) используется вместо самих элементов.
>>> test1 = ["a","b","c","d","e","f","g","h","i"]
>>> test2 = [("c",1),("g",1),("b",1),("e",1),("g",1),("d",10),("a",10)]
>>> sorted(test2, key=lambda x: (x[1], test1.index(x[0])))
[('b', 1), ('c', 1), ('e', 1), ('g', 1), ('g', 1), ('a', 10), ('d', 10)]
Учитывая приведенный выше порядок клавиш, сначала по номеру, а затем по test1
,
Использовать dict
сопоставление каждой строки в test1 с ее индексом, поэтому для связей вы сортируете по индексу, и поиск 0(1)
:
test1 = ["a","b","c","d","e","f","g","h","i"]
inds = dict(zip(test1, range(len(test1))))
test2 = [("c",1),("g",1),("b",1),("e",1),("g",1),("d",10),("a",10)]
print(sorted(test2,key=lambda x: (x[1], inds[x[0]])))
Выход:
[('b', 1), ('c', 1), ('e', 1), ('g', 1), ('g', 1), ('a', 10), ('d', 10)]
Если вы действительно хотите, чтобы строки были в отсортированном порядке, вы можете просто использовать саму строку, используя itemgetter
вместо лямбды
test2 = [("c", 1), ("g", 1), ("b", 1), ("e", 1), ("g", 1), ("d", 10), ("a", 10)]
from operator import itemgetter
print(sorted(test2, key=itemgetter(1, 0)))
[('b', 1), ('c', 1), ('e', 1), ('g', 1), ('g', 1), ('a', 10), ('d', 10)]