How to Randomly Select from a List in Python

To randomly select from a list in Python, use random.choice(my_list) for one item. For several items without repeats, use random.sample(my_list, k); with repeats or weights, use random.choices():

import random
random.choice(cities)          # one item
random.sample(cities, 3)       # 3 different items

Each pick below is real output from Python 3.12.5 with NumPy 2.5.3. Most examples use a seed, so you can reproduce them exactly.

You’ll see choice and seeding, sample vs choices, weighted picks, removing what you picked, secure choices with secrets, and NumPy for arrays.

Pick one random item with random.choice()

choice() works on any sequence. Seed the generator when you need the same “random” result every run, like in tests:

import random

cities = ["Austin", "Denver", "Seattle", "Boston", "Miami"]
print(random.choice(cities))            # one random item

random.seed(2026)                        # same seed -> same picks every run
print([random.choice(cities) for _ in range(3)])

try:
    random.choice([])
except IndexError as err:
    print("IndexError:", err)

Output:

Boston
['Austin', 'Seattle', 'Miami']
IndexError: Cannot choose from an empty sequence
Command Prompt output of Python random.choice picking a city, seeded picks, and an IndexError for an empty list
One random city, three seeded picks, and the error you get from an empty list.

Guard against empty lists with if cities: before choosing. For random numbers rather than list items, see generating random numbers in Python.

Select several items: sample() vs choices()

sample() never repeats an item, so it can’t return more than the list holds. choices() draws with replacement, so repeats are allowed:

import random

random.seed(7)
customers = ["Emily", "James", "Olivia", "Noah", "Ava", "Liam"]

print("sample (no repeats):", random.sample(customers, 3))
print("choices (repeats ok):", random.choices(customers, k=5))

try:
    random.sample(customers, 10)
except ValueError as err:
    print("ValueError:", err)

Output:

sample (no repeats): ['Olivia', 'James', 'Noah']
choices (repeats ok): ['Noah', 'Emily', 'Noah', 'Olivia', 'Emily']
ValueError: Sample larger than population or is negative
Command Prompt output of Python random.sample returning unique customers, random.choices with repeats, and a ValueError when the sample is too large
Three unique customers, five picks that may repeat, and the error when you ask sample() for too many.

To randomize the whole list instead, use random.shuffle(); I cover it in shuffling a list in Python.

How do you make a weighted random selection?

Pass weights to choices(). Here’s a prize draw where the big gift card should be rare, run 10,000 times to check the odds:

import random
from collections import Counter

random.seed(42)
prizes = ["$5.00 coupon", "$20.00 gift card", "$100.00 gift card"]
weights = [80, 18, 2]                    # percent chance of each prize

draws = random.choices(prizes, weights=weights, k=10_000)
for prize, n in Counter(draws).most_common():
    print(f"{prize:<18} {n:>5} draws ({n / 100:.1f}%)")

Output:

$5.00 coupon        8031 draws (80.3%)
$20.00 gift card    1765 draws (17.6%)
$100.00 gift card    204 draws (2.0%)
Command Prompt output of Python random.choices with weights over 10,000 draws showing coupon, gift card and large gift card frequencies
The tallies land close to the 80/18/2 weights.

Weights don’t need to add up to 100; they’re relative. Building the list of results is covered in generating a list of random numbers.

Remove the picked item, use secrets, or NumPy

For a draw without putting names back, pop a random index. For codes and tokens, use secrets, which is designed for security. For big arrays, NumPy’s generator is fast and supports probabilities:

import random
import secrets

random.seed(3)
entrants = ["Emily", "James", "Olivia", "Noah"]
winner = entrants.pop(random.randrange(len(entrants)))   # pick AND remove
print("winner:", winner, "| still in the draw:", entrants)

alphabet = "ABCDEFGHJKMNPQRSTUVWXYZ23456789"
code = "".join(secrets.choice(alphabet) for _ in range(8))  # for tokens and codes
print("promo code length:", len(code), "| all from alphabet:", set(code) <= set(alphabet))

import numpy as np
rng = np.random.default_rng(1)
print(rng.choice(["small", "medium", "large"], size=6, p=[0.5, 0.3, 0.2]))

Output:

winner: James | still in the draw: ['Emily', 'Olivia', 'Noah']
promo code length: 8 | all from alphabet: True
['medium' 'large' 'small' 'large' 'small' 'small']
Command Prompt output of Python popping a random winner from a list, building an 8-character code with secrets.choice, and NumPy choice with probabilities
The winner leaves the list, the promo code uses only allowed characters, and NumPy picks sizes with the given odds.

Never use random for passwords or reset links; its output can be predicted. NumPy’s random tools are covered in NumPy random in Python.

Which random selection method should you use?

I start with choice() or sample() and only reach for weights, secrets or NumPy when the job needs them. Removing items afterwards is covered in removing an element from a list by index.

GoalUse
One itemrandom.choice(lst)
Several unique itemsrandom.sample(lst, k)
Several items, repeats or weightsrandom.choices(lst, weights=..., k=n)
Pick and removelst.pop(random.randrange(len(lst)))
Security-sensitivesecrets.choice(lst)
Large arraysnumpy.random.default_rng().choice()

These guides go well with random selection:

Frequently asked questions

How do I randomly select an item from a list in Python?

Use random.choice(my_list), after import random.

How do I pick several random items without repeats?

Use random.sample(my_list, k). k can’t be larger than the list.

What’s the difference between sample() and choices()?

sample() picks unique items; choices() picks with replacement and supports weights.

How do I get the same random result every time?

Call random.seed(n) with a fixed number before picking.

Is random.choice safe for passwords?

No. Use secrets.choice() for passwords, tokens and codes.

Where is the random module documented?

See random in the Python docs.