python
shuffle
array
randomize
programming

Shuffle an array with python, randomize array item order with python

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Introduction

Randomizing item order is common in testing, games, simulations, and machine learning preprocessing. In Python, the right shuffle method depends on whether you want to mutate the original list, return a new randomized list, or guarantee reproducibility with a seed. Knowing these differences prevents subtle bugs and inconsistent results.

Shuffle In Place with random.shuffle

random.shuffle modifies the list directly and returns None. This is efficient and usually the best choice when you no longer need the original ordering.

python
1import random
2
3cards = ["A", "K", "Q", "J", "10"]
4random.shuffle(cards)
5print(cards)

Because it mutates in place, avoid assigning its return value.

python
1import random
2
3items = [1, 2, 3]
4result = random.shuffle(items)
5print(result)  # None
6print(items)   # Shuffled list

Create a Shuffled Copy with random.sample

If original order must remain intact, use random.sample with full length.

python
1import random
2
3numbers = [1, 2, 3, 4, 5]
4shuffled_copy = random.sample(numbers, k=len(numbers))
5
6print("original:", numbers)
7print("copy:", shuffled_copy)

This pattern is helpful when you want deterministic comparisons between original and randomized data.

Reproducible Shuffling with Seeds

For tests and experiments, use a local Random instance with a fixed seed. This avoids global random-state side effects.

python
1import random
2
3values = list(range(10))
4rng = random.Random(2026)
5rng.shuffle(values)
6
7print(values)

Use local generators in libraries so your function does not unexpectedly influence randomness in other modules.

Shuffle NumPy Arrays for Data Workloads

For numeric workloads, NumPy provides vectorized tools. numpy.random.Generator.permutation returns a shuffled copy, while Generator.shuffle can mutate arrays in place.

python
1import numpy as np
2
3rng = np.random.default_rng(seed=7)
4arr = np.array([10, 20, 30, 40, 50])
5
6shuffled_copy = rng.permutation(arr)
7rng.shuffle(arr)
8
9print("copy:", shuffled_copy)
10print("in place:", arr)

For aligned feature and label arrays, shuffle indices once and apply them to all arrays to preserve pairings.

python
1import numpy as np
2
3rng = np.random.default_rng(42)
4X = np.array([[1, 1], [2, 2], [3, 3], [4, 4]])
5y = np.array([0, 1, 0, 1])
6
7idx = rng.permutation(len(X))
8X_shuf = X[idx]
9y_shuf = y[idx]
10
11print(X_shuf)
12print(y_shuf)

Fisher-Yates Implementation for Full Control

Python already implements robust shuffling, but writing Fisher-Yates manually is useful for learning or custom random sources.

python
1from random import Random
2
3
4def fisher_yates(items: list[int], seed: int | None = None) -> list[int]:
5    rng = Random(seed)
6    out = items.copy()
7
8    for i in range(len(out) - 1, 0, -1):
9        j = rng.randint(0, i)
10        out[i], out[j] = out[j], out[i]
11
12    return out
13
14
15print(fisher_yates([1, 2, 3, 4, 5], seed=11))

This returns a new list and keeps input unchanged.

Choosing the Right Method

Use random.shuffle for fast in-place list randomization. Use random.sample when you need an independent shuffled copy. Use seeded local generators for deterministic behavior in tests and reproducible experiments. For matrix-heavy pipelines, prefer NumPy generators for better integration and performance.

Make your choice explicit in code comments or function names so callers understand whether mutation occurs.

Common Pitfalls

The most frequent mistake is expecting random.shuffle to return a shuffled list. It returns None, so assigning it creates confusing bugs. Another issue is seeding global random state in shared code, which can make unrelated tests flaky. In machine learning code, shuffling features without shuffling labels by the same index can silently corrupt training data. Developers also forget that randomness alone does not ensure balanced splits, so stratification may still be needed depending on the task.

Summary

  • random.shuffle is in-place and efficient for mutable lists.
  • random.sample returns a shuffled copy while preserving original order.
  • Use local seeded generators for reproducibility and test stability.
  • With NumPy, shuffle indices once to keep arrays aligned.
  • Be explicit about mutation to prevent hidden side effects.

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

All Rights Reserved.