Come unire due set in una riga senza usare “|”


171

Supponiamo che Se Tsiano assegnati set. Senza usare l'operatore join |, come posso trovare l'unione dei due set? Questo, ad esempio, trova l'intersezione:

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

Quindi, come posso trovare l'unione di due set in una riga senza usare |?


1
hai bisogno di unirti? Se sì, allora puoi fare s.union (t)
Ansuman Bebarta,

59
Perché non puoi usare |?
Scott Bartell,

1
Qualche motivo generico per non usare |?
matanster

5
Un motivo potrebbe essere passare un'operazione impostata come argomento di funzione. Immaginate una funzione, qualcosa come: def apply_set_operation(a, b, set_operation). Quando si chiama questa funzione, preferirei apply_set_operation(a, b, set.union)aapply_set_operation(a, b, set.__or__)
BSA

Risposte:


309

Puoi usare il metodo union per i set: set.union(other_set)

Si noti che restituisce un nuovo set, ovvero non si modifica da solo.


54
Tuttavia, è |possibile modificare la variabile in linea:set_a |= set_b
jorgenkg,

13
@jorgenkg stesso di: set_a = set_a.union(set_b). Se intendi "sul posto", nessuno dei due lo farà, entrambi creeranno un nuovoset
nettamente il

3
@jorgenkg crea ancora un nuovo set e sostituisce il riferimento.
Alvaro,

3
@Alvaro @nitely secondo un semplice test a = set((1, 2, 3,)); b = set((1, 3, 4,)); id_a = id(a); a |= b; assert id_a == id(a):, @jorgenkg ha ragione - la variabile aviene modificata in linea. Mi sto perdendo qualcosa?
johndodo,

3
No, non sembra che: a = set((1, 2, 3,)); b = set((1, 3, 4,)); c = a; a |= b; assert id(c) == id(a). Anche se afosse stato distrutto, cnon lo sarebbe stato. Inoltre, cè ora set([1, 2, 3, 4]), quindi il commento di @ jorgenkg è corretto.
johndodo,

45

È possibile utilizzare l' or_alias:

>>> 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
adoro questo approccio, più funzionale, e potrebbe essere applicato a 2 o più set.
Colin Su

42

Se stai bene modificando il set originale (cosa che potresti voler fare in alcuni casi), puoi usare set.update():

S.update(T)

Il valore restituito è None, ma Sverrà aggiornato per essere l'unione dell'originale Se T.


23

Supponendo che anche tu non possa usare s.union(t), il che equivale a s | t, potresti provare

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

Oppure, se vuoi una comprensione,

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

14

Se per join intendi unione, prova questo:

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

È un po 'un trucco, ma non riesco a pensare a una migliore linea per farlo.


set (list (s) + list (t)) ti darà lo stesso risultato se farai un sindacato.
Ansuman Bebarta,

Sono consapevole, ma sembra che stesse cercando di evitare di usare le funzioni integrate in Python, altrimenti avrebbe semplicemente usato il | operatore.
BenjaminCohen,

liste setsono incorporate nelle funzioni Python
whackamadoodle3000

10

Supponiamo di avere 2 elenchi

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

così puoi trovare AUnion Bcome segue

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

anche se vuoi trovare intersezione e non intersezione, fallo come segue

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

7

Puoi semplicemente decomprimere entrambi i set in uno in questo modo:

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

Il *disimballa il set. Il disimballaggio è dove viene rappresentato un iterabile (ad esempio un set o un elenco) come ogni articolo che produce. Ciò significa che l'esempio sopra semplifica e {1, 2, 3, 4, 3, 4, 5, 6}poi semplifica {1, 2, 3, 4, 5, 6}perché l'insieme può contenere solo elementi univoci.


Cosa fa la *riga 3?
altabq

5

Puoi fare uniono semplice comprensione dell'elenco

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

A avrebbe tutti gli elementi di B


usare la comprensione dell'elenco per gli effetti collaterali e con parametri anonimi è una pessima pratica.
Jean-François Fabre
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.