Сортировка списка по частичному совпадению в другом списке

Рассмотрим этот список.

input_list = ['Saturday', 'Tuesday', 'Sunday', 'Monday', 'Thursday', 'Wednesday', 'Cheeseburger', 'Friday']

Я хочу отсортировать его на основе частичных совпадений второго списка.

list_sorter = ['Mon', 'Tue', 'Wed']

чтобы

output_list = ['Monday', 'Tuesday', 'Wednesday', 'Cheeseburger', 'Friday', 'Saturday', 'Sunday','Thursday']

Предпочтительно хранить отсортированный список в input_list. Заранее спасибо за помощь.

Редактировать:

Я пробовал sorted(input_list, key = list_sorter.index)

Какие ошибки.

ValueError: «Суббота» отсутствует в списке

Я пробовал sorted(input_list, key = lambda x: x in list_sorter)

Что тоже не правильно.

Редактировать 2: не следует предполагать, что текст находится в начале слова. Извините за позднее редактирование, мне это не пришло в голову, пока я не увидел ответы.

list_sorter = ['Mon', 'Tue', 'rida']
output_list = ['Monday', 'Tuesday','Friday','Cheeseburger', 'Saturday', 'Sunday','Thursday','Wednesday']

когда в list_sorter также должно поддерживаться частичное совпадение.


person Joylove    schedule 10.12.2018    source источник
comment
Итак, что вы пробовали? В то время как некоторые отвечающие могут чувствовать себя великодушными и все равно отвечать, у вас гораздо больше шансов получить ответ, если вы пытались решить проблему самостоятельно и можете показать свою работу (и что с ней не так). Этот вопрос читается как домашнее задание, и Stack Overflow здесь не для того, чтобы сделать домашнее задание за вас. Подсказка: попробуйте написать функцию, которую можно передать как параметр key объекта list.sort.   -  person Blckknght    schedule 10.12.2018
comment
что ты уже испробовал? Ваши образцы не имеют для меня особого смысла. Пожалуйста, объясните, что вам нужно.   -  person Pedro Lobito    schedule 10.12.2018
comment
есть ли правило для слов, не связанных с list_sorter?   -  person B. M.    schedule 11.12.2018
comment
Слова, не включенные в list_sorter, я бы хотел, чтобы они либо сортировались по алфавиту, либо сохранялись в порядке. Так что я контролирую порядок. list_sorter ранжирует input_list по наиболее важным первым словам, а остальные слова имеют тот же ранг.   -  person Joylove    schedule 11.12.2018
comment
@Joylove, я обновил свое решение; слова, не покрытые, находятся в сохраненном порядке.   -  person jpp    schedule 11.12.2018


Ответы (3)


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

sort_map = {day: next((idx for idx, val in enumerate(list_sorter) if val in day),
                 len(input_list)) for day in input_list}

res = sorted(input_list, key=sort_map.__getitem__)

['Monday', 'Tuesday', 'Friday', 'Saturday', 'Sunday',
 'Thursday', 'Wednesday', 'Cheeseburger']
person jpp    schedule 10.12.2018
comment
это работает, потому что stackoverflow.com/ вопросы/39980323/; может опасно? - person B. M.; 10.12.2018
comment
@BM, Нет, мое решение не зависит от упорядочения словарей. sort_map сопоставляется с целыми числами, порядок dict не предполагается. - person jpp; 10.12.2018
comment
Хорошо, я понял. Я был обеспокоен тем, что «Чизбургер» стоял в алфавитном порядке, но это случайная функция. Так что нет проблем. - person B. M.; 11.12.2018

Сначала создайте словарь с информацией о сортировке в O(len(list_sorter)+len(input_list)):

order=dict.fromkeys([x[:3] for x in input_list],len(list_sorter))
order.update({k:v for (v,k) in enumerate(list_sorter)})
#{'Sat': 3, 'Tue': 1, 'Sun': 3, 'Mon': 0, 'Thu': 3, 'Wed': 2, 'Che': 3, 'Fri': 3}

Затем отсортируйте:

res=sorted(input_list, key = lambda x : (order[x[:3]],x[:3]))
#['Monday', 'Tuesday', 'Wednesday', 'Cheeseburger', 'Friday', \
#  'Saturday', 'Sunday', 'Thursday']  

Неиспользуемые слова располагаются в конце в алфавитном порядке.

person B. M.    schedule 10.12.2018

Я не уверен, как вы получаете порядок несортированных элементов в своем списке, поэтому я предполагаю, что они не отсортированы.

Вот пример:

        input_list = ['Saturday', 'Tuesday', 'Sunday', 'Monday', 'Thursday', 'Wednesday', 'Cheeseburger', 'Friday']
        list_sorter = ['Mon', 'Tue', 'Wed']
        list_sorter.reverse()
        tupple_list = []
        for element in input_list:
            sub_string = element[0:3]
            if sub_string in list_sorter:
                index = list_sorter.index(sub_string) + 1
            else:
                index = 0
            tupple_list.append((element, index))
        sorted_list = sorted(tupple_list, key=lambda x: x[1], reverse = True)
        output_list = []
        for tupple in sorted_list:
            output_list.append(tupple[0])
        print (output_list)

Предоставление:

['Monday', 'Tuesday', 'Wednesday', 'Saturday', 'Sunday', 'Thursday', 'Cheeseburger', 'Friday']
person Steve    schedule 10.12.2018