Jak połączyć dwa zestawy w jednej linii bez użycia „|”


171

Załóżmy, że Si Tsą przypisane zestawy. |Jak mogę znaleźć sumę dwóch zbiorów bez użycia operatora łączenia ? To na przykład znajduje przecięcie:

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

Jak więc mogę znaleźć sumę dwóch zestawów w jednej linii bez użycia |?


1
czy potrzebujesz zjednoczenia? Jeśli tak, możesz zrobić s.union (t)
Ansuman Bebarta

59
Dlaczego nie możesz użyć |?
Scott Bartell,

1
Jest jakiś ogólny powód, aby nie używać |?
matanster

5
Jednym z powodów może być przekazanie operacji zestawu jako argumentu funkcji. Wyobraźmy sobie funkcję, coś takiego: def apply_set_operation(a, b, set_operation). Po wywołaniu tej funkcji, wolałbym apply_set_operation(a, b, set.union), abyapply_set_operation(a, b, set.__or__)
bsa

Odpowiedzi:


309

Możesz użyć metody sumowania dla zestawów: set.union(other_set)

Zwróć uwagę, że zwraca nowy zestaw, tj. Nie modyfikuje się.


54
Jednak |można zmodyfikować zmienną inline:set_a |= set_b
jorgenkg

13
@jorgenkg samo jak: set_a = set_a.union(set_b). Jeśli masz na myśli „na miejscu”, żadne z nich nie zrobi tego, oba tworzą noweset
ostatecznie

3
@jorgenkg nadal tworzy nowy zestaw i zastępuje odniesienie.
Alvaro

3
@Alvaro @nitely zgodnie z prostym testem a = set((1, 2, 3,)); b = set((1, 3, 4,)); id_a = id(a); a |= b; assert id_a == id(a):, @jorgenkg ma rację - zmienna ajest modyfikowana w tekście . Czy coś mi brakuje?
johndodo

3
Nie, nie wygląda na to: a = set((1, 2, 3,)); b = set((1, 3, 4,)); c = a; a |= b; assert id(c) == id(a). Nawet gdyby azostał zniszczony, cnie zostałby. Również cteraz jest set([1, 2, 3, 4]), więc komentarz @ jorgenkg jest poprawny.
johndodo

45

Możesz użyć or_aliasu:

>>> 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
Uwielbiam to podejście, bardziej funkcjonalne i można je zastosować do 2 lub więcej zestawów.
Colin Su,

42

Jeśli możesz modyfikować oryginalny zestaw (co możesz zrobić w niektórych przypadkach), możesz użyć set.update():

S.update(T)

Wartość zwracana to None, ale Szostanie zaktualizowana, aby była sumą oryginału Si T.


23

Zakładając, że nie możesz również użyć s.union(t), co jest równoważne s | t, możesz spróbować

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

Lub, jeśli chcesz zrozumieć,

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

14

Jeśli przez dołączenie masz na myśli związek, spróbuj tego:

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

To trochę hack, ale nie mogę wymyślić lepszego jednego liniowca, aby to zrobić.


set (list (s) + list (t)) da ci ten sam wynik, jeśli zrobisz związek.
Ansuman Bebarta

Wiem, ale wygląda na to, że próbował uniknąć używania wbudowanych funkcji Pythona, w przeciwnym razie użyłby tylko | operator.
BenjaminCohen

listi setsą wbudowane w funkcje Pythona
whackamadoodle3000

10

Załóżmy, że masz 2 listy

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

więc możesz znaleźć AUnion Bw następujący sposób

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

również jeśli chcesz znaleźć przecięcie i brak przecięcia, wykonaj to w następujący sposób

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

7

Możesz po prostu rozpakować oba zestawy do jednego w ten sposób:

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

*Rozpakowuje zestawu. Rozpakowywanie polega na tym, że element iterowalny (np. Zestaw lub lista) jest reprezentowany jako każdy otrzymany element. Oznacza to, że powyższy przykład upraszcza się, {1, 2, 3, 4, 3, 4, 5, 6}a następnie upraszcza, {1, 2, 3, 4, 5, 6}ponieważ zestaw może zawierać tylko unikalne elementy.


Co robi *w linii 3?
altabq

5

Możesz zrobić unionlub po prostu zrozumieć listę

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

A miałby wszystkie elementy B.


używanie rozumienia list dla skutków ubocznych i anonimowych parametrów jest bardzo złą praktyką.
Jean-François Fabre
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.