Basta usare qualsiasi:
if any(myvar in x for x in (r,s,t))
set le ricerche sono 0(1)
creando così un'unione per verificare se la variabile è in ogni set è del tutto inutile invece di controllare semplicemente utilizzando in
con any
che si interrompe non appena viene trovata una corrispondenza e non crea una nuova serie.
E mi chiedo anche se questa unione influenzerà in qualche modo performance del
Sì, certo unioning i set influisce sulle prestazioni, si aggiunge alla complessità, si sta creando un nuovo insieme ogni volta che è O(len(r)+len(s)+len(t))
in modo da possiamo dire addio al vero punto di utilizzo di set che sono ricerche efficienti.
Così la linea di fondo è che è si desidera mantenere le ricerche efficienti si dovrà unione il set una volta e tenere in memoria la creazione di una nuova variabile quindi utilizzando quella di fare la tua ricerca per myvar
così la creazione iniziale sarà 0(n)
e le ricerche saranno 0(1)
in seguito.
Se non si desidera effettuare una ricerca prima di creare l'unione, non si avrà una soluzione lineare nella lunghezza di r+s+t -> set.union(*(r, s, t))
rispetto alle peggiori tre ricerche costanti (in media). Ciò significa anche aggiungere o rimuovere sempre elementi dal nuovo set unione aggiunti/rimossi da r,s
o t
.
Alcune tempi realistici su insiemi moderatamente grandi dimensioni mostrano esattamente la differenza:
In [1]: r = set(range(10000))
In [2]: s = set(range(10001,20000))
In [3]: t = set(range(20001,30000))
In [4]: timeit any(29000 in st for st in (r,s,t))
1000000 loops, best of 3: 869 ns per loop
In [5]: timeit 29000 in r | s | t
1000 loops, best of 3: 956 µs per loop
In [6]: timeit 29000 in reduce(lambda x,y :x.union(y),[r,s,t])
1000 loops, best of 3: 961 µs per loop
In [7]: timeit 29000 in r.union(s).union(t)
1000 loops, best of 3: 953 µs per loop
Timing gli spettacoli sindacali che praticamente tutto il tempo è speso nelle chiamate sindacali:
In [8]: timeit r.union(s).union(t)
1000 loops, best of 3: 952 µs per loop
Utilizzando più grande imposta e ottenere l'elemento in ultimo set:
In [15]: r = set(range(1000000))
In [16]: s = set(range(1000001,2000000))
In [17]: t = set(range(2000001,3000000))
In [18]: timeit any(2999999 in st for st in (r,s,t))
1000000 loops, best of 3: 878 ns per loop
In [19]: timeit 2999999 in reduce(lambda x,y :x.union(y),[r,s,t])
1 loops, best of 3: 161 ms per loop
In [20]: timeit 2999999 in r | s | t
10 loops, best of 3: 157 ms per loop
C'è l non importa, non importa quanto grande sia il set che usa any
ma man mano che le dimensioni del set crescono, così il tempo di esecuzione viene utilizzato con union.
L'unico modo per renderlo più veloce sarebbe quella di attenersi a or
ma ci stanno prendendo la differenza di poche centinaia di nanosecondi, che è il costo della creazione del generatore di espressione e la chiamata di funzione:
In [22]: timeit 2999999 in r or 2999999 in s or 2999999 in t
10000000 loops, best of 3: 152 ns per loop
Per set sindacali set.union (* (r, s, t)) è anche il più veloce come non costruire set di intermedie:
In [47]: timeit 2999999 in set.union(*(r,s,t))
10 loops, best of 3: 108 ms per loop
In [49]: r | s | t == set.union(*(r,s,t))
Out[49]: True
So che il titolo di "Come controllare se un valore è presente in nessuno dei set di dati" suona un po 'strano. Se qualcuno vede un modo migliore per scriverlo, sentiti libero di modificarlo! – fedorqui