Domanda Come estrarre il membro dal set di membri singoli in python?


Recentemente ho riscontrato uno scenario in cui, se un set conteneva solo un singolo elemento, volevo fare qualcosa con quell'elemento. Per ottenere l'elemento, ho optato per questo approccio:

element = list(myset)[0]

Ma questo non è molto soddisfacente, in quanto crea una lista non necessaria. Potrebbe anche essere fatto con l'iterazione, ma l'iterazione sembra anche innaturale, dal momento che esiste un solo elemento. Mi sto perdendo qualcosa di semplice?


44
2017-10-24 23:41


origine


risposte:


Tuple disfare i lavori.

(element,) = myset

(A proposito, python-dev ha esplorato ma ha respinto l'aggiunta di myset.get() per restituire un elemento arbitrario da un set. Discussione qui, Risponde Guido van Rossum 1 e 2.)

Il mio preferito per ottenere un elemento arbitrario è (quando hai un numero sconosciuto, ma funziona anche se ne hai uno solo):

element = next(iter(myset)) ¹

1: in Python 2.5 e precedenti, devi usare iter(myset).next()


66
2017-10-24 23:54



Tra fare una tupla e fare un iteratore, è quasi un lavaggio, ma l'iterazione vince per un naso ...:

$ python2.6 -mtimeit -s'x=set([1])' 'a=tuple(x)[0]'
1000000 loops, best of 3: 0.465 usec per loop
$ python2.6 -mtimeit -s'x=set([1])' 'a=tuple(x)[0]'
1000000 loops, best of 3: 0.465 usec per loop
$ python2.6 -mtimeit -s'x=set([1])' 'a=next(iter(x))'
1000000 loops, best of 3: 0.456 usec per loop
$ python2.6 -mtimeit -s'x=set([1])' 'a=next(iter(x))'
1000000 loops, best of 3: 0.456 usec per loop

Non sei sicuro del motivo per cui tutte le risposte utilizzano la sintassi più vecchia iter(x).next() piuttosto che il nuovo next(iter(x)), che mi sembra preferibile (e funziona anche in Python 3.1).

Tuttavia, il disimballaggio vince a mani basse su entrambi:

$ python2.6 -mtimeit -s'x=set([1])' 'a,=x'
10000000 loops, best of 3: 0.174 usec per loop
$ python2.6 -mtimeit -s'x=set([1])' 'a,=x'
10000000 loops, best of 3: 0.174 usec per loop

Questo ovviamente è per i set di singoli elementi (in cui la forma di quest'ultimo, come altri menzionati, ha il vantaggio di non riuscire velocemente se il set che "sapevi" avesse solo un elemento in realtà ne aveva diversi). Per gli insiemi con elementi N> 1 arbitrari, la tupla rallenta, l'iter no:

$ python2.6 -mtimeit -s'x=set(range(99))' 'a=next(iter(x))'
1000000 loops, best of 3: 0.417 usec per loop
$ python2.6 -mtimeit -s'x=set(range(99))' 'a=tuple(x)[0]'
100000 loops, best of 3: 3.12 usec per loop

Quindi, disimballaggio per il caso singleton, e next(iter(x)) per il caso generale, sembra meglio.


17
2017-10-25 08:05



suppongo La risposta di kaizer.se è grande. Ma se il tuo set potrebbe contiene più di un elemento e vuoi un elemento non così arbitrario, potresti volerlo usare min o max. Per esempio.:

element = min(myset)

o:

element = max(myset)

(Non usare sorted, perché ha inutili spese generali per questo utilizzo.)


11
2017-12-20 02:59



Puoi usare element = tuple(myset)[0] che è un po 'più efficiente, oppure puoi fare qualcosa del genere

element = iter(myset).next()

Immagino che la costruzione di un iteratore sia più efficiente della costruzione di una tupla / lista.


2
2017-10-24 23:59



Suggerisco:

element = myset.pop()

2
2018-04-19 04:25