2013-07-23 8 views
6

Vorrei ottenere un elemento da un frozenset (senza modificarlo, ovviamente, dato che i frozenset sono immutabili). La soluzione migliore che ho trovato finora è:Come ottenere un elemento arbitrario da un frozenset?

s = frozenset(['a']) 
iter(s).next() 

che ritorna, come previsto:

'a' 

In altre parole, c'è un modo di 'popping' un elemento da un frozenset senza realmente popping vero?

+4

Penso che il vostro metodo è come Se vuoi un elemento casuale, puoi controllare 'random.sample (fset, 1)'. – bbayles

+0

Perché vuoi far apparire l'elemento, perché è arbitrario? – martineau

+1

Voglio solo ottenere qualche elemento arbitrario da un frozenset: non avrei dovuto usare la parola pop dato che il set rimane invariato ed è simile a sbirciare il fi primo elemento di una pila senza scoppiarlo. – ablondin

risposta

5

(Riassumendo le risposte fornite nei commenti)

Il vostro metodo è buono come qualsiasi, con l'avvertenza che, da Python 2.6, si dovrebbe utilizzare next(iter(s)) piuttosto che iter(s).next().

Se si desidera un caso elemento piuttosto che un arbitraria uno, utilizzare il seguente:

import random 
random.sample(s, 1)[0] 

Qui ci sono un paio di esempi che dimostrano la differenza tra i due:

>>> s = frozenset("kapow") 
>>> [next(iter(s)) for _ in range(10)] 
['a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a'] 
>>> import random 
>>> [random.sample(s, 1)[0] for _ in range(10)] 
['w', 'a', 'o', 'o', 'w', 'o', 'k', 'k', 'p', 'k'] 
+0

Perché dovresti chiamare 'next (iter (s))' piuttosto che 'iter (s) .next()'? – rynemccall

+2

@rynemccall Perché in Python 3, ['iter.next()' non esiste] (https://www.python.org/dev/peps/pep-3114/). –

7

Se sai che lì non è che un elemento della frozenset, è possibile utilizzare disimballaggio iterabile:

s = frozenset(['a']) 
x, = s 

Questo è un po un caso speciale della domanda originale, ma viene in aiuto a volte.

Se si dispone di un sacco di questi per farlo potrebbe essere più veloce di prossima (iter ..:

>>> timeit.timeit('a,b = foo', setup='foo = frozenset(range(2))', number=100000000) 
5.054765939712524 
>>> timeit.timeit('a = next(iter(foo))', setup='foo = frozenset(range(2))', number=100000000) 
11.258678197860718 
+0

'ValueError: troppi valori per decomprimere' sul set con più elementi. –

+0

come detto, funziona solo con * esattamente * un elemento nel frozenset. –

2

Si potrebbe usare con Python 3:

>>> s = frozenset(['a', 'b', 'c', 'd']) 
>>> x, *_ = s 
>>> x 
'a' 
>>> _, x, *_ = s 
>>> x 
'b' 
>>> *_, x, _ = s 
>>> x 
'c' 
>>> *_, x = s 
>>> x 
'd' 
+0

Funziona anche per i dizionari. – tammoj

Problemi correlati