Как проверить, есть ли один из элементов одного списка, в элементе другого списка?

Есть 2 списка:

a = ["привет", "заказ", "123", "100", "шт", "345", "500бухт", "и", "678", "700м"]

b = ["шт", "бухт", "м"]

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

['500бухт', '700м']

Делать это через 2 цикла или есть проще выход?


Ответы (6 шт):

Автор решения: nomnoms12

Да, делать через 2 цикла. Если хотите сократить код, то можете воспользоваться списковым включением.

Пример:

a = ['привет', 'заказ', '123', '100', 'шт', '345', '500бухт', 'и', '678', '700м']
b = ['шт', 'бухт', 'м']

d = [x for y in b for x in a if y in x and x != y]
print(d)

stdout:

['500бухт', '700м']
→ Ссылка
Автор решения: SergFSM

Ну при желании можно одним циклом обойтись, правда не уверен, что так будет лучше:

a = ['привет', 'заказ', '123', '100', 'шт', '345', '500бухт', 'и', '678', '700м']
b = ['шт', 'бухт', 'м']

c = [*filter(lambda x: any(i in x for i in b if i!=x), a)]  # ['500бухт', '700м']
→ Ссылка
Автор решения: CrazyElf

Это смотря что называть циклом. Вот вместо двух вложенных for два filter с lambda, но по сути то это всё-равно цикл в цикле сложностью O(n^2):

print(list(filter(lambda x: any(filter(lambda y: y in x and x != y, b)), a)))

Вывод:

['500бухт', '700м']

P.S. Кстати, MaxU прав - мало ли где внутри слова может встретиться буква "м". Лучше, наверное, и правда использовать регулярки, ну или хотя бы проверять не через in, а через endswith, если строка из b должна быть в конце строки, и что до того идёт число тоже можно проверить без регулярок через isdigit:

print(list(
    filter(lambda x: any(
        filter(lambda y: x.endswith(y) and
                      x[:-len(y)].isdigit() and
                      x != y,
               b)
        ), a)
    ))
→ Ссылка
Автор решения: SergFSM

совсем без циклов получилось собрать такую неуклюжую, но рабочую конструкцию:

import pandas as pd

arr = pd.Series(a)
expr = '|'.join(b)
c = arr[arr.str.contains(expr,regex=True)&~arr.str.fullmatch(expr)].to_list()

# ['500бухт', '700м']
→ Ссылка
Автор решения: MaxU

По-моему данную задачу нужно решать используя регулярные выражения. Наверняка у вас в реальном списке будут слова, в которых встречается буква "м" и которые не имеют никакого отношения к метрам.

import re

a = ["привет", "трям!", "заказ", "123", "100", "шт", "345", "500бухт", "и", "678", "700м"]
b = ["шт", "бухт", "м"]

pat = r"\d+\s*(?:{})".format("|".join(b))
res = [x for x in a if re.search(pat, x)]

результат:

In [522]: res
Out[522]: ['500бухт', '700м']
→ Ссылка
Автор решения: Vladimir
List1 = ['python', 'JS', 'c#', 'go', 'c', 'c++']
List2 = ['c#', 'Java', 'python']

check = any(item in List1 for item in List2)

if check:
    print("The list1 contains some elements of the list2")
else:
    print("No, List1 doesn't have any elements of the List2.")
→ Ссылка