Reputation: 447
I would like to get an element from a frozenset
(without modifying it, of course, as frozenset
s are immutable). The best solution I have found so far is:
s = frozenset(['a'])
iter(s).next()
which returns, as expected:
'a'
In other words, is there any way of 'popping' an element from a frozenset
without actually popping it?
Upvotes: 31
Views: 28956
Reputation: 34046
Using list
:
list_ = list(frozenset("Benyamin"))
Using generator
:
def get_frozenset_elements(frozen_set):
for i in frozen_set:
yield i
gen_ = get_frozenset_elements(frozenset("Benyamin"))
next(gen_)
next(gen_)
next(gen_)
...
Using iterator
:
iter_ = iter(frozenset("Benyamin"))
next(gen_)
next(gen_)
next(gen_)
...
[NOTE]:
Difference between Python's Generators and Iterators
Upvotes: 1
Reputation: 948
You could use with python 3:
>>> s = frozenset(['a', 'b', 'c', 'd'])
>>> x, *_ = s
>>> x
'a'
>>> _, x, *_ = s
>>> x
'b'
>>> *_, x, _ = s
>>> x
'c'
>>> *_, x = s
>>> x
'd'
Upvotes: 12
Reputation: 251
If you know that there is but one element in the frozenset, you can use iterable unpacking:
s = frozenset(['a'])
x, = s
This is somewhat a special case of the original question, but it comes in handy some times.
If you have a lot of these to do it might be faster than next(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
Upvotes: 24
Reputation: 59148
(Summarizing the answers given in the comments)
Your method is as good as any, with the caveat that, from Python 2.6, you should be using next(iter(s))
rather than iter(s).next()
.
If you want a random element rather than an arbitrary one, use the following:
import random
random.sample(s, 1)[0]
Here are a couple of examples demonstrating the difference between those two:
>>> 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']
Upvotes: 20