Как проверить, есть ли все элементы в списке в другом списке? - программирование
Подтвердить что ты не робот

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

У меня есть два списка:

List1 = ['a','c','c']
List2 = ['x','b','a','x','c','y','c']

Теперь я хочу узнать, есть ли все элементы List1 в List2. В этом случае все есть. Я не могу использовать функцию подмножества, потому что я могу повторять элементы в списках. Я могу использовать цикл for для подсчета количества вхождений каждого элемента в List1 и посмотреть, меньше или равно количеству вхождений в List2. Есть ли лучший способ сделать это?

Спасибо.

4b9b3361

Ответ 1

Вы все еще можете использовать функциональность подмножества, создав набор "на лету":

>>> list1 = ['a', 'c', 'c']
>>> list2 = ['x', 'b', 'a', 'x', 'c', 'y', 'c']
>>> set(list1) < set(list2)
True

Или, если вы хотите проверить, совпадает ли количество вхождений, вы можете использовать тип Counter и определить свое собственное отношение подмножества:

>>> from collections import Counter
>>> def counterSubset(list1, list2):
        c1, c2 = Counter(list1), Counter(list2)
        for k, n in c1.items():
            if n > c2[k]:
                return False
        return True

>>> counterSubset(list1, list2)
True
>>> counterSubset(list1 + ['a'], list2)
False
>>> counterSubset(list1 + ['z'], list2)
False

Если у вас уже есть счетчики (это может быть полезной альтернативой для хранения ваших данных), вы также можете просто написать это как одну строку:

>>> all(n <= c2[k] for k, n in c1.items())
True

Ответ 2

Обратите внимание на следующее:

>>>listA = ['a', 'a', 'b','b','b','c']
>>>listB = ['b', 'a','a','b','c','d']
>>>all(item in listB for item in listA)
True

Если вы читаете строку "все", как и на английском, это не так, но может вводить в заблуждение, так как listA имеет третий "b", но listB этого не делает.

Это также имеет ту же проблему:

def list1InList2(list1, list2):
    for item in list1:
        if item not in list2:
            return False
    return True

Просто заметьте. Не работает следующее:

>>>tupA = (1,2,3,4,5,6,7,8,9)
>>>tupB = (1,2,3,4,5,6,6,7,8,9)
>>>set(tupA) < set(TupB)
False

Если вы конвертируете кортежи в списки, он все равно не работает. Я не знаю, почему строки работают, но нет.

Работает, но имеет одинаковую проблему с тем, чтобы не учитывать количество элементов:

>>>set(tupA).issubset(set(tupB))
True

Использование наборов не является исчерпывающим решением для сопоставления элементов с несколькими событиями.

Но вот однострочное решение/адаптация к ответу shantanoo без try/except:

all(True if sequenceA.count(item) <= sequenceB.count(item) else False for item in sequenceA)

Встроенная функция, обертывающая понимание списка с использованием тернарного условного оператора. Python потрясающий! Обратите внимание, что "< =" не должно быть "==".

С помощью этой последовательности решений A и B могут быть типичными кортежами и списками и другими "последовательностями" с методами "count". Элементы в обеих последовательностях могут быть самыми разными. Я бы не использовал это с dicts, как сейчас, поэтому вместо "итерабельной" используйте "последовательность".

Ответ 3

def check_subset(list1, list2):
    try:
        [list2.remove(x) for x in list1]
        return 'all elements in list1 are in list2'
    except:
        return 'some elements in list1 are not in list2'

Ответ 4

Это вернет true, все элементы в List1 находятся в List2

def list1InList2(list1, list2):
    for item in list1:
        if item not in list2:
            return False
    return True