To shuffle a list in Python, call random.shuffle(my_list). It reorders the list in place and returns None, so don’t assign the result. For a shuffled copy that leaves the original alone, use random.sample(my_list, k=len(my_list)):
import random
random.shuffle(playlist) # playlist is now shuffled
I seeded the generator in most examples so the printed order matches the screenshots; the outputs come from Python 3.12.5.
You’ll see shuffle and sample, repeatable shuffles with a seed, tuples and strings, shuffling two lists in step, and secure draws for giveaways.
Shuffle a list with random.shuffle()
shuffle() changes the list itself. The most common bug is writing playlist = random.shuffle(playlist), which sets the variable to None:
import random
random.seed(2026) # only so this demo prints the same order every run
playlist = ["Austin", "Boston", "Chicago", "Denver", "El Paso"]
result = random.shuffle(playlist) # shuffles in place
print(playlist)
print("return value:", result)
copy = random.sample(playlist, k=len(playlist)) # new shuffled list, original untouched
print(copy)
print(playlist)
Output:
['Boston', 'El Paso', 'Denver', 'Chicago', 'Austin']
return value: None
['El Paso', 'Chicago', 'Denver', 'Austin', 'Boston']
['Boston', 'El Paso', 'Denver', 'Chicago', 'Austin']

Use sample() when other code still needs the original order. To pick one or a few items instead, see randomly selecting from a list in Python.
How do I shuffle a list the same way every time?
Seed the generator first. The same seed gives the same order, which is what you want in tests and reproducible reports:
import random
deck = list(range(1, 11))
for run in range(2):
random.seed(42)
d = deck[:]
random.shuffle(d)
print(f"seed 42, run {run + 1}:", d)
rng = random.Random(7) # a private generator, independent of the global one
d = deck[:]
rng.shuffle(d)
print("Random(7): ", d)
Output:
seed 42, run 1: [8, 4, 3, 9, 6, 7, 10, 5, 1, 2]
seed 42, run 2: [8, 4, 3, 9, 6, 7, 10, 5, 1, 2]
Random(7): [9, 4, 2, 5, 8, 1, 10, 7, 3, 6]

A random.Random instance keeps its own state, so seeding it doesn’t affect other code. For generating random values in general, see generating random numbers in Python.
Shuffle a tuple or a string
Tuples and strings can’t be changed in place, so shuffle() raises a TypeError. sample() works on any sequence and returns a list:
import random
random.seed(5)
states = ("TX", "CA", "NY", "FL")
try:
random.shuffle(states)
except TypeError as err:
print("TypeError:", err)
print(tuple(random.sample(states, k=len(states))))
word = "PYTHON"
print("".join(random.sample(word, k=len(word))))
Output:
TypeError: 'tuple' object does not support item assignment
('NY', 'FL', 'TX', 'CA')
YPNOHT

Join the sampled characters to get a string back. There’s a full walkthrough in shuffling characters in a string.
Shuffle two lists together in the same order
When two lists line up item by item, shuffling them separately breaks the pairs. Zip them, shuffle the pairs, then unzip:
import random
random.seed(11)
names = ["Emily", "James", "Olivia", "Liam", "Ava"]
scores = [92, 85, 78, 88, 95]
pairs = list(zip(names, scores))
random.shuffle(pairs)
names, scores = map(list, zip(*pairs))
print(names)
print(scores)
print(dict(zip(names, scores))["Olivia"], "<- Olivia still has her own score")
Output:
['Olivia', 'Emily', 'James', 'Ava', 'Liam']
[78, 92, 85, 95, 88]
78 <- Olivia still has her own score

zip(*pairs) is the unzip step. If you’d rather keep the pairs together permanently, a dictionary is easier, as in creating a dictionary from two lists.
Shuffle securely for draws and giveaways
The random module is predictable by design. For prize draws or anything people could try to game, use random.SystemRandom or the secrets module:
import random
import secrets
entries = ["emily@example.com", "james@example.com", "olivia@example.com", "liam@example.com"]
draw = random.SystemRandom() # uses the OS's secure random source, can't be seeded
order = entries[:]
draw.shuffle(order)
print("draw order:", order)
print("winner:", secrets.choice(entries))
batch = list(range(1, 21))
random.seed(3)
random.shuffle(batch)
cut = int(len(batch) * 0.8)
print("train:", batch[:cut])
print("test: ", batch[cut:])
Output:
draw order: ['james@example.com', 'emily@example.com', 'liam@example.com', 'olivia@example.com']
winner: james@example.com
train: [9, 4, 7, 6, 16, 17, 3, 13, 1, 2, 14, 11, 20, 10, 15, 12]
test: [5, 18, 19, 8]
The second half shows the everyday shuffle-then-split for an 80/20 train/test cut. To fill a list with random values first, see generating a list of random numbers.
Shuffling options compared
| Need | Use |
|---|---|
| Shuffle in place | random.shuffle(lst) |
| Shuffled copy | random.sample(lst, k=len(lst)) |
| Same order every run | random.seed(n) or random.Random(n) |
| Tuple or string | random.sample(seq, k=len(seq)) |
| Two lists in step | Shuffle list(zip(a, b)) |
| Fair public draw | random.SystemRandom().shuffle(lst) |
A few more list and random tutorials:
- Generate random numbers between 0 and 1
- Generate a random string of a given length
- Find duplicates in a Python list
- Get the last element of a list
Frequently asked questions
How do I shuffle a list in Python?
Use random.shuffle(my_list), which shuffles it in place.
Why does random.shuffle return None?
It changes the list itself instead of making a new one. Use random.sample(lst, k=len(lst)) for a copy.
How do I get the same shuffle every time?
Call random.seed(42) before shuffling, or use a random.Random(42) instance.
Can I shuffle a tuple?
Not in place. Use tuple(random.sample(t, k=len(t))).
Is random.shuffle secure enough for a giveaway?
No. Use random.SystemRandom().shuffle() or the secrets module.
Where is random.shuffle documented?
See random.shuffle() in the Python docs.

Bijay Kumar is a 13-time Microsoft MVP with more than 18 years in software development, and the founder of Python Guides and TSinfo Technologies. He started out building .NET and SharePoint solutions at HP, TCS and KPIT before moving into Python, machine learning and AI, and he also builds web apps with TypeScript and React. He writes the tutorials here himself, and every example is run before publishing so you see the real output. More about Bijay · Microsoft MVP profile · LinkedIn