Подтвердить что ты не робот

Найти элементы, которые встречаются в некоторых, но не во всех списках

Предположим, что у меня есть несколько списков целых чисел:

[0,3,4]
[2,3,4,7]
[2,3,4,6]

Какой самый эффективный/самый pythonic способ создать единый список всех элементов, которые встречаются хотя бы в одном списке, но не встречаются во всех списках? В этом случае это будет

[0,2,7,6]
4b9b3361

Ответ 1

Ответ подразумевается в вашем вопросе.. если вы замените "набор" на "списки". Как опубликовал StephenTG, просто получите разницу между объединением и пересечением всех списков.

Преимущество использования наборов над Counter заключается в том, что вам не нужно делать никаких предположений о значениях, появляющихся только один раз в каждом списке.

Следующие работы независимо от того, сколько у вас списков:

> list_of_sets = [set(l) for l in lists]
> set.union(*list_of_sets) - set.intersection(*list_of_sets)
{0, 2, 6, 7}

Ответ 2

Вы можете взять пересечение всех списков в виде набора и объединение всех списков в виде набора и взять все элементы в объединении, которые не находятся в пересечении. Существуют методы union, intersection и difference для обработки, которые документированы здесь

>>> union_set = set(l1).union(l2,l3)
>>> intersection_set = set(l1).intersection(l2,l3)
>>> union_set - intersection_set
set([0, 2, 6, 7])

Или, как показывает ответ kdopen, вы можете создать список наборов, если вы не знаете точное количество списков, с которыми вы будете иметь дело

Ответ 3

Если мы предположим, что каждый список содержит элемент не более одного раза, вы можете использовать счетчик для подсчета количества вхождений каждого элемента. Затем вы можете выбирать элементы, которые не встречаются столько раз, сколько количество входных списков:

from itertools import chain
from collections import Counter

lists = [
    [0, 3, 4],
    [2, 3, 4, 7],
    [2, 3, 4, 6]
]

print [x for x, c in Counter(chain(*lists)).items() if c != len(lists)]

Результат:

[0, 2, 6, 7]