How to Shuffle a List in Python

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']
Command Prompt output of Python random.shuffle reordering a list in place and returning None, and random.sample making a shuffled copy
The playlist is reordered, shuffle() returns None, and random.sample() gives a second order while the playlist stays as it was.

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]
Command Prompt output of Python shuffling a list twice with seed 42 to get the same order, and with a separate Random(7) generator
Both seed-42 runs print the identical order, and the private Random(7) generator gives its own fixed order.

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
Command Prompt output of Python TypeError tuple object does not support item assignment from random.shuffle, then random.sample on a tuple and string
Shuffling the tuple fails with item assignment TypeError, while sample() returns a shuffled tuple and a scrambled word.

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
Command Prompt output of Python shuffling a names list and scores list together with zip so each name keeps its score
Both lists come out in the same new order, and Olivia still maps to her score of 78.

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

NeedUse
Shuffle in placerandom.shuffle(lst)
Shuffled copyrandom.sample(lst, k=len(lst))
Same order every runrandom.seed(n) or random.Random(n)
Tuple or stringrandom.sample(seq, k=len(seq))
Two lists in stepShuffle list(zip(a, b))
Fair public drawrandom.SystemRandom().shuffle(lst)

A few more list and random tutorials:

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.