2010-10-28 5 views

risposta

154

dal set, vuoi dire set?

>>> foo = set(range(0, 4)) 
>>> foo 
set([0, 1, 2, 3]) 
>>> foo.update(range(2, 6)) 
>>> foo 
set([0, 1, 2, 3, 4, 5]) 
+3

Sì, non mi aspettavo che fosse ambiguo, ma sembra che sia :) L'aggiornamento è proprio la cosa. Grazie! –

+2

Ho appena ripensato alla mia sessione di interprete e in realtà l'ho provato, ma ho pensato che aveva aggiunto l'intera lista come un elemento del set a causa delle parentesi quadre nella rappresentazione del set. Non avevo mai notato prima che fossero rappresentati così. –

+6

Questa rappresentazione consente di incollarla di nuovo in una sessione interattiva, perché il costruttore 'set' prende un argomento iterabile come argomento. –

-4

mi piace questo modo:

set = [item for item in items] 
+0

@dolma, io non voglio creare * * un nuovo set, ma aggiungere a un set esistente. Scusa se non era chiaro; Ho modificato la domanda per chiarire. –

+0

@dolma, inoltre, (a) puoi fare 's = set (items)' e (b) il tuo esempio ridefinisce un built-in :) –

+0

quindi puoi semplicemente fare 'set.extend ([item per item in items ]) ', Immagino ... – dolma33

-1

Usa di lista.

corto circuito la creazione di iterabile usando una lista ad esempio :)

>>> x = [1, 2, 3, 4] 
>>> 
>>> k = x.__iter__() 
>>> k 
<listiterator object at 0x100517490> 
>>> l = [y for y in k] 
>>> l 
[1, 2, 3, 4] 
>>> 
>>> z = Set([1,2]) 
>>> z.update(l) 
>>> z 
set([1, 2, 3, 4]) 
>>> 

[Edit: mancava la parte insieme di domanda]

+1

Non vedo nessun set? Mi sto perdendo qualcosa? –

+1

@Ian Mackinnon: Aah! Ha perso completamente quel punto. Grazie. – pyfunc

-1
for item in items: 
    extant_set.add(item) 

Per la cronaca, credo che l'affermazione che "Ci dovrebbe essere tra-- e, preferibilmente, un solo modo --obvious per farlo." è fasullo. Presuppone che molte persone con idee tecniche creino, che tutti la pensano allo stesso modo. Ciò che è ovvio per una persona non è così ovvio per un altro.

Direi che la mia soluzione proposta è chiaramente leggibile e fa quello che chiedi. Non credo che ci siano dei successi nelle performance, anche se ammetto che potrei mancare qualcosa. Ma nonostante tutto, potrebbe non essere ovvio e preferibile a un altro sviluppatore.

+0

Argh! Il ciclo for che si trova su una riga del genere è formattato nella mia risposta: non lo farei mai. Mai. – jaydel

+1

set usa 'add' not' append' – FogleBird

+0

Hai assolutamente ragione. Ho modificato il post per riparare il mio danno. Grazie :) – jaydel

0

Imposta hanno il metodo add troppo:

>>> s=set([1,2,3,4]) 
>>> for n in range(10): 
     s.add(n) 
>>> s 
set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) 
7

È possibile utilizzare la funzione set() per convertire un iterabile in un set, e quindi utilizzare operatore di aggiornamento insieme standard (| =) per aggiungere i valori univoci dal tuo nuovo set a quello esistente.

>>> a = { 1, 2, 3 } 
>>> b = (3, 4, 5) 
>>> a |= set(b) 
>>> a 
set([1, 2, 3, 4, 5]) 
+4

L'uso di '.update' ha il vantaggio che l'argomento può essere qualsiasi iterabile, non necessariamente un set, a differenza dell'RHS dell'operatore' | = 'nell'esempio. – tzot

+1

Buon punto. È solo una scelta estetica dato che set() può convertire un iterabile in un set, ma il numero di sequenze di tasti è lo stesso. – gbc

+0

Non l'ho mai visto prima, mi divertirò a usarlo quando verrà visualizzato in futuro; Grazie! – eipxen

30

Per il beneficio di chiunque possa credere ad es. che facendo aset.add() in un ciclo avrebbe prestazioni competitive con il fare aset.update(), ecco un esempio di come è possibile testare le vostre convinzioni in fretta prima di andare pubblico:

>\python27\python -mtimeit -s"it=xrange(10000);a=set(xrange(100))" "a.update(it)" 
1000 loops, best of 3: 294 usec per loop 

>\python27\python -mtimeit -s"it=xrange(10000);a=set(xrange(100))" "for i in it:a.add(i)" 
1000 loops, best of 3: 950 usec per loop 

>\python27\python -mtimeit -s"it=xrange(10000);a=set(xrange(100))" "a |= set(it)" 
1000 loops, best of 3: 458 usec per loop 

>\python27\python -mtimeit -s"it=xrange(20000);a=set(xrange(100))" "a.update(it)" 
1000 loops, best of 3: 598 usec per loop 

>\python27\python -mtimeit -s"it=xrange(20000);a=set(xrange(100))" "for i in it:a.add(i)" 
1000 loops, best of 3: 1.89 msec per loop 

>\python27\python -mtimeit -s"it=xrange(20000);a=set(xrange(100))" "a |= set(it)" 
1000 loops, best of 3: 891 usec per loop 

Sembra che il costo per punto di un approccio ciclo è più di tre volte quello dell'approccio update.

L'utilizzo di |= set() costa circa 1,5 volte il valore di update ma metà di ciò che aggiunge ogni singolo elemento in un ciclo.

0

Solo un rapido aggiornamento, timing utilizzando Python 3:

#!/usr/local/bin python3 
from timeit import Timer 

a = set(range(1, 100000)) 
b = list(range(50000, 150000)) 

def one_by_one(s, l): 
    for i in l: 
     s.add(i)  

def cast_to_list_and_back(s, l): 
    s = set(list(s) + l) 

def update_set(s,l): 
    s.update(l) 

risultati sono:

one_by_one 10.184448844986036 
cast_to_list_and_back 7.969255169969983 
update_set 2.212590195937082