2013-10-25 2 views
46

Я делаю некоторый набор операций в Python, и я заметил что-то странное ..Python set Union и set Intersection работают по-разному?

>> set([1,2,3]) | set([2,3,4]) 
set([1, 2, 3, 4]) 
>> set().union(*[[1,2,3], [2,3,4]]) 
set([1, 2, 3, 4]) 

Это хорошо, ожидаемое поведение - но с пересечением:

>> set([1,2,3]) & set([2,3,4]) 
set([2, 3]) 
>> set().intersection(*[[1,2,3], [2,3,4]]) 
set([]) 

Могу ли я схожу с ума здесь? Почему функция set.intersection() не работает, как я ожидал?

Как я могу выполнить пересечение множества множеств, как это было с объединением (если [[1,2,3], [2,3,4]] имел целую группу больше списков)? Каким был бы «пифонический» путь?

ответ

74

Когда вы делаете set(), вы создаете пустой набор. Когда вы делаете set().intersection(...), вы пересекаете этот пустой набор с другими вещами. Пересечение пустого множества с любым другим набором множеств пусто.

Если у вас на самом деле есть список комплектов, вы можете получить их пересечение, похожее на то, как вы это сделали.

>>> x = [{1, 2, 3}, {2, 3, 4}, {3, 4, 5}] 
>>> set.intersection(*x) 
set([3]) 

Вы не можете сделать это напрямую с тем, как вы делаете это, хотя, потому что вы на самом деле не имеют каких-либо наборов вообще в вашем примере с intersection(*...). У вас есть только список . Сначала вы должны преобразовать элементы в свой список в настройки. Так что если у вас есть

x = [[1,2,3], [2,3,4]] 

вы должны сделать

x = [set(a) for a in x] 
1

[удален неправильный ответ]

Как @Anto Vinish предложил сначала вы должны преобразовать списки наборов, а затем использовать set.intersection

Например:

>>> sets = [set([1, 2, 3]), set([2, 3, 4]), set([3, 4, 5])] 
>>> set.intersection(*sets) 
set([3]) 
+0

Как бы пересекаться много наборов в аналогично тому, как я объединил многих? –

+0

Извините, мой ответ неправильный – Hypuk

+2

@Hypuk Если ответ неверный, то вы можете его удалить (если хотите) –

9

преобразовать список, чтобы установить первый

>>> set.intersection(*[set([1,2,3]), set([2,3,4])]) 
set([2, 3]) 

Для нескольких списков вы можете просто использовать,

>>> set.intersection(*[set([1,2,3]), set([2,3,4]), set([5,3,4])]) 
set([3]) 
+3

'set.intersection' отличается от' set(). Intersection' – roippi

+0

Однако он достигает результата I'm находясь в поиске –

13
set().intersection(*[[1,2,3], [2,3,4]]) 

, конечно, пустой, потому что вы начинаете с пустым множеством и пересекаете ее со всеми другие

Вы можете попробовать позвонить по этому методу на class

set.intersection(*[[1,2,3], [2,3,4]]) 

, но это не будет работать, потому что первый аргумент, передаваемый должен быть набор

set.intersection({1, 2, 3}, *[[2,3,4], ...]) 

Это выглядит неудобно, лучше, если вы могли бы использовать список наборов, в первую очередь.Особенно, если они исходят от генератора, что делает его трудно снять первый элемент чисто

set.intersection(*[{1,2,3}, {2,3,4}]) 

В противном случае вы можете просто сделать их все в наборы

set.intersection(*(set(x) for x in [[1,2,3], [2,3,4]])) 
Смежные вопросы