Last Updated: Saturday 27th December 2014

One of the most common tasks that requires random action is selecting one item from a group, be it a character from a string, unicode, or buffer, a byte from a bytearray, or an item from a list, tuple, set, or xrange. It's also common to want a sample of more than one item.

Don't do this when randomly selecting an item

A naive approach to these tasks involves something like the following; to select a single item, you would use randrange (or randint) from the random module, which generates a pseudo-random integer from the range indicated by its arguments:

An equally naive way to select multiple items might use random.randrange to generate indexes inside a list comprehension, as in:

These work, but as you should expect if you've been writing Python for any length of time, there's a built-in way of doing it that is briefer and more readable.

Do this instead, when selecting an item

The pythonic way to select a single item from a Python sequence type — that's any of str, unicode, list, tuple, bytearray, buffer, xrange — is to use random.choice. For example, the last line of our single-item selection would be:

Much simpler, isn't it? There's an equally simple way to select n items from the sequence:

Randomly selecting from a set

sets are not indexable, meaning set([1, 2, 3])[0] produces an error. Therefore random.choice does not support sets, however random.sample does.

For example:

There are several ways to get around this, 2 of which are to convert the set to a list first, and to use random.sample which does support sets.


Duplicate Items

If the sequence contains duplicate values, each one is an independent candidate for selection. To avoid duplicates, one method would be to convert the list into a set, and back into a list. For example:

  • Drew

    Awesome, thanks for the tip!

  • John Doe

    random.choice CANNOT operate on sets.

    • Jackson Cooper

      Thanks for pointing that out, I’ve edited the article to reflect this.