Ответ 1
Используйте оператор симметричной разности для set
(также оператор XOR):
>>> set([1,2,3]) ^ set([3,4,5])
set([1, 2, 4, 5])
Я пытаюсь написать фрагмент кода, который может автоматически выражать выражение. Например, если у меня есть два списка [1,2,3,4] и [2,3,5], код должен иметь возможность находить общие элементы в двух списках [2,3] и объединять остальные элементов в новом списке, [1,4,5].
Из этого сообщения: Как найти перекресток списка? Я вижу, что общие элементы можно найти через
set([1,2,3,4]&set([2,3,5]).
Есть ли простой способ получить не общие элементы из каждого списка, в моем примере это [1,4] и [5]?
Я могу продолжить и сделать цикл for:
lists = [[1,2,3,4],[2,3,5]]
conCommon = []
common = [2,3]
for elem in lists:
for elem in eachList:
if elem not in common:
nonCommon += elem
Но это кажется излишним и неэффективным. Предоставляет ли Python какую-нибудь удобную функцию, которая может это сделать? Спасибо заранее!
Используйте оператор симметричной разности для set
(также оператор XOR):
>>> set([1,2,3]) ^ set([3,4,5])
set([1, 2, 4, 5])
Вы можете использовать концепцию Intersection для решения таких проблем.
b1 = [1,2,3,4,5,9,11,15]
b2 = [4,5,6,7,8]
set(b1).intersection(b2)
Out[22]: {4, 5}
Лучше всего использовать этот код, он работает довольно быстро и для больших данных. У меня есть b1 с 607139 и b2 с 296029 элементами, когда я использую эту логику, я получаю свои результаты за 2,9 секунды.
Вы можете использовать метод атрибута .__xor__
.
set([1,2,3,4]).__xor__(set([2,3,5]))
или
a = set([1,2,3,4])
b = set([2,3,5])
a.__xor__(b)
Старый вопрос, но похоже, что в python есть встроенная функция, чтобы обеспечить именно то, что вы ищете: .difference()
.
ПРИМЕР
list_one = [1,2,3,4]
list_two = [2,3,5]
one_not_two = set(list_one).difference(list_two)
# set([1, 4])
two_not_one = set(list_two).difference(list_one)
# set([5])
Как примечание - кажется, что ОП ищет решение, которое предоставляет два отдельных списка (или набора) - один, где первый содержит элементы, а не второй, и наоборот. Большинство предыдущих ответов возвращают один список или набор, включающий все элементы.
Существует также вопрос относительно того, следует ли считать элементы, которые могут дублироваться в первом списке, несколько раз или только один раз.
Если ФП хочет сохранить дубликаты, может быть использовано понимание списка, например:
one_not_two = [ x for x in list_one if x not in list_two ]
two_not_one = [ x for x in list_two if x not in list_one ]
... что примерно такое же решение, как и в первоначальном вопросе, только немного чище. Этот метод будет поддерживать дубликаты из исходного списка, но значительно медленнее для больших наборов данных.