#python #list #python-2.7
#python #Список #python-2.7
Вопрос:
У меня есть следующие 2 списка Python:
main_l = ['Temp_Farh', 'Surface', 'Heater_back', 'Front_Press',
'Lateral_Cels', 'Gauge_Finl','Gauge_Relay','Temp_Throw','Front_JL']
hlig = ['Temp', 'Lateral', 'Heater','Front']
Мне нужно переместить элементы из main_l
в конец списка, если они содержат строки, перечисленные hlig
в.
Окончательная версия main_l
должна выглядеть следующим образом:
main_l = ['Surface', 'Gauge_Finl','Gauge_Relay', 'Temp_Farh', 'Heater_back', 'Front_Press',
'Lateral_Cels', 'Temp_Throw','Front_JL']
Моя попытка:
Сначала я пытаюсь определить main_l
, содержит ли список элементы с подстрокой, перечисленные во 2-м списке hlig
. Вот как я это делаю:
`found` = [i for e in hlig for i in main_l if e in i]
found
является подсписком main_l
. Проблема в том, что теперь, когда у меня есть этот список, я не знаю, как выбрать элементы, которые НЕ содержат подстрок hlig
. Если бы я мог это сделать, я мог бы добавить их в список not_found
, а затем объединить их следующим образом: not_found found
— и это дало бы мне то, что я хочу.
Вопрос:
Есть ли способ переместить соответствующие элементы в конец списка main_l
?
Комментарии:
1. Всегда ли элементы во втором списке являются префиксами, разделенными символом подчеркивания?
2. Нет. Иногда перед ними не ставится символ подчеркивания.
Ответ №1:
Вы можете сортировать main_l
, используя, содержит ли каждый элемент строку из hlig в качестве ключа:
main_l.sort(key=lambda x: any(term in x for term in hlig))
Комментарии:
1. Вы можете убрать квадратные скобки, чтобы немного уменьшить визуальный шум и включить
any()
короткое замыкание.2. Первое решение стабильно. Нет необходимости во втором.
3. Упс, я предполагал, что это не так. Исправлено.
4. А? Когда я пытаюсь
print main_l.sort(key=lambda x: any(term in x for term in hlig))
, я получаюNone
. PS: я использую Python 2.75.
sort
не возвращает отсортированный список; он сортирует его на месте. Если вы хотите, чтобы он возвращал новый список, используйтеsorted
вместо этого.
Ответ №2:
Я бы переписал то, что вам нужно:
main_l = ['Temp_Farh', 'Surface', 'Heater_back', 'Front_Press', 'Lateral_Cels', 'Gauge_Finl','Gauge_Relay','Temp_Throw','Front_JL']
hlig = ['Temp', 'Lateral', 'Heater','Front']
found = [i for i in main_l if any(e in i for e in hlig)]
Тогда решение очевидно:
not_found = [i for i in main_l if not any(e in i for e in hlig)]
answer = not_found found
РЕДАКТИРОВАТЬ: удалены квадратные скобки вокруг понимания списка на основе комментариев Свена Марнаха (к решению aviraldg)
Комментарии:
1.
if not any
!!!! Вот и все!!! О, это расстраивает! Большое спасибо. Это должно было быть так, как я это сделал. Я попытался изменить свой подход на включениеif e not in i
, но это дало список, который был намного длиннее, чемmain_l
— очевидно, это не работало. Еще раз спасибо, что показали правильный способ сделать это.2. @WR Решение с использованием сортировки быстрее, лаконичнее и изменяет список на месте, поэтому вам также следует его рассмотреть.
3. Согласен, но спасибо за ваш пост. Это поможет мне в других сценариях.
4. @SvenMarnach, спасибо за предложение убрать скобки (хотя оно и не было направлено на мое решение). Сортировка может быть быстрее, когда main_l достаточно короткий, но в какой-то момент, по мере роста main_l, я ожидаю, что сортировка будет медленнее. Конечно, сортировка более элегантна.
5. @jimhark Я не думаю, что это будет медленнее для любого размера. Ключевая функция вычисляется только один раз для каждого элемента, и фактическая сортировка выполняется по возвращенным значениям ключа. Существует только два возможных значения ключа,
False
иTrue
, и для массивов с этим свойством алгоритм Timsort, используемый методом Pythonlist.sort()
, по существу равен O (n) .