#python #python-3.x #list #any
#python #python-3.x #Список #Любой
Вопрос:
У меня есть два списка
list1 = ['B', 'C', 'D']
list2 = [['1', 'A'], ['2', 'B'], ['3', 'D'], ['5', 'C']]
и хотите вернуть те подсписки list2, которые содержат элементы list1.
До сих пор я пытался использовать любой:
result = []
for l2 in list2:
if any (item in l2 for item in list1):
result.append(l2)
и наивный подход
for l2 in list2:
for l1 in l1:
if l1 in l2:
result.append(l2)
Но мне удалось только повторить пустой список.
Результат должен быть
result = [['2', 'B'], ['5', 'C']]
Не уверен, где я ошибаюсь. Может быть, есть способ использовать понимание списка или смешивать понимание списка и «любую» функцию?
Комментарии:
1. Где это
['3', 'D']
?2. Ваш первый фрагмент кода должен выдавать ожидаемый результат, а не пустой список. Вы запустили свой код?
3. То же самое относится и ко второму фрагменту кода — за исключением опечатки:
for l1 in list1:
Ответ №1:
То, что у вас есть, выглядит правильно и работает для меня локально тоже:
for l2 in list2:
if any (item in l2 for item in list1):
result.append(l2)
Он возвращает [['2', 'B'], ['3', 'D'], ['5', 'C']]
ожидаемый результат, верно?
Также обратите внимание, что вы можете ускорить свою реализацию, изменив list1 на set list1 = set(['B', 'C', 'D'])
и изменив условие if на if any (item in list1 for item in l2):
.
Это потому item in list1
, что намного быстрее, если list1
a set
, чем a list
. Это потому set
, что использует hashmap под капотом для быстрого доступа к элементам.
Ответ №2:
Попробуйте это:
result=[i for i in list2 if any([k in i for k in list1])]
print(result)
[['2', 'B'], ['3', 'D'], ['5', 'C']]
Ответ №3:
Если элементы являются хешируемыми объектами (как в данном случае со строками), то вы можете использовать set intersection:
>>> list1 = ['B', 'C', 'D']
>>> list2 = [['1', 'A'], ['2', 'B'], ['3', 'D'], ['5', 'C']]
>>> s = set(list1)
>>> [l for l in list2 if set(l) amp; s]
[['2', 'B'], ['3', 'D'], ['5', 'C']]
Если пересечение пустое, то это обрабатывается как значение false для целей if
фильтрации в понимании списка.
Тем не менее, я не могу воспроизвести тот факт, что ваш (первый) код в вопросе не работает для вас; он отлично работает, когда я пытаюсь это сделать. Ваш второй фрагмент кода (помимо опечатки) имеет потенциальную проблему с дублированием подсписков в выходных данных, потому что вы не break
делаете этого из внутреннего цикла после нахождения первого соответствующего элемента.