Python устанавливает соединение и устанавливает пересечение работать по-разному?
Я делаю некоторые операции набора в Python, и я заметил что-то странное.
>> 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]]
имел целую группу больше списков)? Каким будет "питонический" способ?
Ответы
Ответ 1
Когда вы делаете 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]
Ответ 2
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]]))
Ответ 3
конвертировать список для установки первого
>>> 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])
Ответ 4
[удален неверный ответ]
Поскольку @Anto Vinish предложил вам сначала преобразовать списки для установки, а затем использовать set.intersect ion.
Например:
>>> sets = [set([1, 2, 3]), set([2, 3, 4]), set([3, 4, 5])]
>>> set.intersection(*sets)
set([3])