How to get an arbitrary element from a frozenset?

18,646

Solution 1

(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']

Solution 2

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

Solution 3

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'
Share:
18,646

Related videos on Youtube

ablondin
Author by

ablondin

Updated on September 16, 2022

Comments

  • ablondin
    ablondin over 1 year

    I would like to get an element from a frozenset (without modifying it, of course, as frozensets 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?

    • bbayles
      bbayles almost 11 years
      I think your method is as good as any. If you want a random element you might check out random.sample(fset, 1).
    • ablondin
      ablondin almost 11 years
      I just want to get some arbitrary element from a frozenset. I shouldn't have used the word pop since the set remains unchanged. It is similar to peeking the first element of a stack without popping it.
    • user2357112
      user2357112 almost 11 years
      That's what I use (but with the next builtin instead of the method).
    • Bakuriu
      Bakuriu almost 11 years
      Don't use the method .next(). There is a next() built-in function since at least python2.6 and using it means that your code will work also in python3 where the next method was renamed __next__.
  • rynemccall
    rynemccall over 9 years
    Why should you call next(iter(s)) rather than iter(s).next()?
  • Zero Piraeus
    Zero Piraeus over 9 years
    @rynemccall Because in Python 3, iter.next() doesn't exist.
  • A T
    A T over 7 years
    ValueError: too many values to unpack on set with multiple elements.
  • Dominic Kempf
    Dominic Kempf over 7 years
    as said, this only works with exactly one element in the frozenset.
  • wchargin
    wchargin over 4 years
    The first of these is just a complicated way to write list(my_frozenset), which is quite wasteful for large sets. The second is just a complicated way to write next(iter(my_frozenset)), which is already the accepted answer.