#python #sorting
#python #сортировка
Вопрос:
У меня есть список элементов, которые мне нужно отсортировать, но значение, которое я хочу использовать при сортировке для каждого элемента, отсутствует в самом списке. Информация о сортировке находится в другом списке, который позиционно совпадает с первым.
Т. е. l = список элементов для сортировки, v = список значений для сортировки. При сортировке l[0] следует использовать значение в v[0] .
Поэтому во время сортировки мне нужно, чтобы python сообщал мне порядковую позицию сортируемого элемента, вместо того, чтобы указывать сам элемент.
Настолько эффективно, что я бы сделал это:
l = sort(key = lambda index_of_item: v[index_of_item])
По умолчанию я думаю, что это не сработает, поскольку python вызывает эту лямбду с фактическим элементом из l, а не с позицией элемента. Есть ли способ заставить python указать мне позицию вместо этого?
(Если бы в каждом сортируемом элементе был какой-то идентификатор, я мог бы использовать его сам внутри лямбда-выражения для экстраполяции index_of_item, но, к сожалению, этого нет)
Комментарии:
1.
list.index()
илиenumerate()
должно быть жизнеспособным для этого2. можете ли вы показать несколько тестовых примеров? пример ввода и вывода?
Ответ №1:
Преобразуйте свой список элементов в список кортежей, который включает исходный индекс; это можно сделать с помощью enumerate()
. Затем вы можете использовать этот индекс для доступа к другому списку.
augumented_list = list(enumerate(l))
augmented_list.sort(key = lambda item: v[item[0]])
result = [x[1] for x in augmented_list]
Другой вариант — использовать zip()
для объединения элементов обоих списков, а затем использовать значение из другого списка в качестве ключа сортировки.
result = [x[0] for x in sorted(zip(l, v), key = lambda x: x[1])]
Комментарии:
1. Пока вы полагаетесь на
enumerate
, вы также можете использоватьsorted
для объединенияlist
ification и сортировки в один шаг:augmented_list = sorted(enumerate(l), key=lambda item: v[item[0]])
2. Да, я просто подумал, что было бы понятнее показать все шаги отдельно. Я объединил все в своем втором решении.
3. ответом был enumerate, но это немного некрасиво — вам нужно «избавиться» от порядковых номеров перечисления после сортировки. Было бы здорово, если бы python каким-то образом необязательно передавал индекс элемента, обеспечивая дополнительный уровень косвенности
4. Тот факт, что у вас есть два отдельных списка для связанных данных, в первую очередь указывает на плохие структуры данных. объедините их в список кортежей или словарей.
5. @MichaelRayLovett: Если вы действительно ненавидите это, «умный» способ сделать это, который я настоятельно не рекомендую , — полагаться на то, что он генерирует ключи для каждого элемента по порядку. Таким образом, вы могли бы обойтись без ручного оформления, выполнив:
l.sort(key=lambda _, it=iter(v): next(it))
. Работает с оригиналомl
без ручного оформления (key
аргументы неявно украшают, сортируют и отменяют оформление, но вам не нужно делать это самостоятельно). ЧТОБЫ БЫЛО ЯСНО, ЭТО УЖАСНАЯ ИДЕЯ! Ничто официально не требует генерации ключей по порядку, это просто естественный способ сделать это.