Как соединить два набора в одну строку, не используя «|»


171

Предположим, что Sи Tназначены наборы. Без использования оператора соединения |, как я могу найти объединение двух наборов? Это, например, находит пересечение:

S = {1, 2, 3, 4}
T = {3, 4, 5, 6}
S_intersect_T = { i for i in S if i in T }

Так как же найти объединение двух множеств в одной строке без использования |?


1
тебе нужно объединиться? Если да, то вы можете сделать s.union (t)
Ansuman Bebarta

59
Почему ты не можешь использовать |?
Скотт Бартелл

1
Любая общая причина не использовать |?
matanster

5
Одной из причин может быть передача операции set в качестве аргумента функции. Представьте себе функцию, что - то вроде: def apply_set_operation(a, b, set_operation). При вызове этой функции, я бы предпочел , apply_set_operation(a, b, set.union)чтобыapply_set_operation(a, b, set.__or__)
БС

Ответы:


309

Вы можете использовать метод объединения для наборов: set.union(other_set)

Обратите внимание, что он возвращает новый набор, т.е. он не меняет себя.


54
Тем не менее, |можно изменить встроенную переменную:set_a |= set_b
jorgenkg

13
@jorgenkg же , как: set_a = set_a.union(set_b). Если вы имеете в виду «на месте», ни один из них не сделает этого, оба создадут новоеset
конечно,

3
@jorgenkg все еще создает новый набор и заменяет ссылку.
Альваро

3
@ Alvaro @ в соответствии с простым тестом: a = set((1, 2, 3,)); b = set((1, 3, 4,)); id_a = id(a); a |= b; assert id_a == id(a)@jorgenkg является правым - переменная aизменяется внутри строки . Я что-то упускаю?
Johndodo

3
Нет, не похоже на это a = set((1, 2, 3,)); b = set((1, 3, 4,)); c = a; a |= b; assert id(c) == id(a). Даже если бы aбыл разрушен, cне был бы. Кроме того, cсейчас set([1, 2, 3, 4]), поэтому комментарий @ jorgenkg является правильным.
Джондо

45

Вы можете использовать or_псевдоним:

>>> from operator import or_
>>> from functools import reduce # python3 required
>>> reduce(or_, [{1, 2, 3, 4}, {3, 4, 5, 6}])
set([1, 2, 3, 4, 5, 6])

9
люблю этот подход, более функциональный, и может быть применен к 2 или более сетов.
Колин Су

42

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

S.update(T)

Возвращаемое значение есть None, но Sбудет обновлено, чтобы быть объединением оригинала Sи T.


23

Предполагая, что вы также не можете использовать s.union(t), что эквивалентно s | t, вы можете попробовать

>>> from itertools import chain
>>> set(chain(s,t))
set([1, 2, 3, 4, 5, 6])

Или, если вы хотите понимания,

>>> {i for j in (s,t) for i in j}
set([1, 2, 3, 4, 5, 6])

14

Если под словом присоединиться вы подразумеваете союз, попробуйте это:

set(list(s) + list(t))

Это что-то вроде хака, но я не могу придумать лучшего лайнера для этого.


set (list (s) + list (t)) даст вам тот же результат, если вы сделаете объединение.
Ансуман Бебарта

Я знаю, но похоже, что он пытался избежать использования встроенных функций python, иначе он просто использовал бы | оператор.
БенджаминКохен

listи setвстроены в функции Python
whackamadoodle3000

10

Предположим, у вас есть 2 списка

 A = [1,2,3,4]
 B = [3,4,5,6]

так что вы можете найти AСоюз, Bкак следует

 union = set(A).union(set(B))

также, если вы хотите найти пересечение и не пересечение, вы делаете это следующим образом

 intersection = set(A).intersection(set(B))
 non_intersection = union - intersection

7

Вы можете просто распаковать оба набора в один так:

>>> set_1 = {1, 2, 3, 4}
>>> set_2 = {3, 4, 5, 6}
>>> union = {*set_1, *set_2}
>>> union
{1, 2, 3, 4, 5, 6}

*Распаковывает набор. Распаковка - это когда итерация (например, набор или список) представляется как каждый элемент, который она дает. Это означает, что приведенный выше пример упрощает, {1, 2, 3, 4, 3, 4, 5, 6}а затем упрощает, {1, 2, 3, 4, 5, 6}потому что набор может содержать только уникальные элементы.


Что делает *в строке 3?
Altabq

5

Вы можете сделать unionили простое понимание списка

[A.add(_) for _ in B]

А будет иметь все элементы Б


использование списочного понимания для побочных эффектов и с анонимным параметром - очень плохая практика.
Жан-Франсуа Фабр
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.