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.

Example:

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.

    • http://jacksonc.com Jackson Cooper

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