random.choice

It computes seq[random index], so it needs len() and indexing: lists, tuples, strings and ranges work; sets fail with TypeError and dicts fail with a confusing KeyError.

random functionAll Python 3 versionsLive demo
Common call
random.choice(['rock', 'paper', 'scissors'])
Returns
one element of the sequence
Replaces
seq[random.randrange(len(seq))]
Watch out
Empty sequence → IndexError; dict → KeyError
random.choice(seqseq — Anything with len() and integer indexing. Must not be empty.type: Sequence · required)
→ object

Demo

Live evaluation
Five independent picks: the same item can come up again.
Try:
Inputs
seedint | stran int or a string
itemslist[str]comma-separated items
Code
import random
random.seed(42)
[random.choice(['apple', 'banana', 'cherry']) for _ in range(5)]
Result
['cherry', 'apple', 'apple', 'cherry', 'banana']

choice() checks len(seq) first, so an empty list or string raises IndexError: Cannot choose from an empty sequence before any random number is drawn. Otherwise it draws an index with _randbelow(len(seq)) (getrandbits plus rejection, exact for any length) and returns seq[index].

Parameters

NameTypeRequiredDescription
seqSequenceyesAnything with len() and integer indexing. Must not be empty.

Return value

object — seq[i] for a uniformly random index i.

Common patterns

Random greeting or response
Pick from a list of alternatives.
import random
reply = random.choice(['Hi!', 'Hello!', 'Hey there!'])
Random key of a dict
Convert to a list first: choice needs indexing.
import random
name = random.choice(list(scores))
name, score = random.choice(list(scores.items()))
Random password character (secure)
secrets.choice has the same interface but an unpredictable source.
import secrets
import string
password = ''.join(secrets.choice(string.ascii_letters + string.digits) for _ in range(16))

Examples

1. Pick from a list
import random random.seed(42) random.choice(['rock', 'paper', 'scissors'])
Returns
'scissors'
2. A character from a string
import random random.seed(42) random.choice('abcdef')
Returns
'f'
3. Coin flips
import random random.seed(42) [random.choice('HT') for _ in range(10)]
Returns
['H', 'H', 'T', 'H', 'H', 'H', 'H', 'H', 'T', 'H']
4. From a range
import random random.seed(42) random.choice(range(100, 200))
Returns
181
5. A random (key, value) pair
import random random.seed(42) users = {'ann': 3, 'bob': 5, 'cy': 1} random.choice(list(users.items()))
Returns
('cy', 1)
6. Empty sequence
import random random.choice([])
Returns
IndexError: Cannot choose from an empty sequence
7. A set is not a sequence
import random random.choice({1, 2, 3})
Returns
TypeError: 'set' object is not subscriptable

Pitfalls

1. Choosing from a dict
A dict has len(), so choice() picks an index and looks it up as a KEY: you get KeyError (or a value whose key happens to be that int). Convert to list(d) or list(d.items()).
choice(dict)
import random
random.seed(42)
random.choice({'a': 1, 'b': 2})
KeyError: 0
choice(list(dict))
import random
random.seed(42)
random.choice(list({'a': 1, 'b': 2}))
'a'
2. Choosing from a set
Sets are unordered and not indexable. Sort them (or list() them, if a repeatable result does not matter) first.
choice(set)
import random
random.seed(42)
random.choice({'x', 'y', 'z'})
TypeError: 'set' object is not subscriptable
choice(sorted(set))
import random
random.seed(42)
random.choice(sorted({'x', 'y', 'z'}))
'z'

When to use

Use it
  • One random element of a list, tuple, str or range
  • Repeated independent picks (with repetition)
Reach for something else
  • Several picks at once → choices(seq, k=n) (with repeats) or sample(seq, n) (without)
  • Weighted picks → choices(seq, weights=...)
  • Secrets → secrets.choice

Notes

CPython impl
Lib/random.py: if not len(seq): raise IndexError('Cannot choose from an empty sequence'); return seq[self._randbelow(len(seq))] — integer arithmetic only, so results are identical on every platform
Why len()
It tests len(seq) instead of truthiness so that NumPy arrays work
vs choices
choices() without weights uses floor(random() * n) instead, so for the same seed it picks different items than repeated choice() calls

FAQ

random.choice(my_list). For several items use random.sample(my_list, k) (no repeats) or random.choices(my_list, k=k) (repeats allowed).