Як з'єднати два набори в одному рядку без використання "|"


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
Однією з причин може бути передача заданої операції як аргумент функції. Уявіть собі функцію, що - щось на кшталт: 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 @nitely згідно з простим тестом:, 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 правильний.
johndodo

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)) дасть вам такий же результат, якщо ви зробите союз.
Ansuman Bebarta

Мені відомо, але, схоже, він намагався уникати використання вбудованих функцій python, інакше він би просто використав | оператор.
BenjaminCohen

listі setвбудовані в функції пітона
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]

A мав би всі елементи B


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