Table of contents
Implement code functionality

How to shuffle a list in Python

May 22, 2025
 ・ by  
the Anthropic Team
Table of contents
H2 Link Template
Try Claude

Python's list shuffling capabilities enable you to randomize element order efficiently. The built-in random module provides the shuffle() function, which implements the Fisher-Yates algorithm for optimal randomization of sequences.

This guide covers essential shuffling techniques, optimization tips, and practical use cases. We created the code examples with Claude, an AI assistant built by Anthropic, to demonstrate effective implementation approaches.

Using random.shuffle() for simple list shuffling

import random
my_list = [1, 2, 3, 4, 5]
random.shuffle(my_list)
print(my_list)
[3, 5, 1, 4, 2]

The random.shuffle() function modifies lists in-place, rearranging elements randomly while maintaining the original data structure. This approach proves more memory-efficient than creating new lists, especially when working with large datasets.

The function implements the Fisher-Yates algorithm, which ensures each permutation has an equal probability of occurring. This makes it particularly useful for:

  • Implementing card games and gambling simulations
  • Randomizing test data sequences
  • Creating fair matchmaking systems

When you call random.shuffle(my_list), Python generates a new random order for the elements [1, 2, 3, 4, 5]. Each execution produces a different sequence, making it ideal for applications requiring true randomization.

Basic shuffling techniques

Beyond the basic random.shuffle() approach, Python offers several alternative methods to randomize lists—from creating shuffled copies with random.sample() to implementing custom algorithms.

Creating a shuffled copy with random.sample()

import random
original_list = [1, 2, 3, 4, 5]
shuffled_list = random.sample(original_list, len(original_list))
print(f"Original: {original_list}")
print(f"Shuffled: {shuffled_list}")
Original: [1, 2, 3, 4, 5]
Shuffled: [5, 2, 1, 3, 4]

Unlike random.shuffle(), the random.sample() function creates a new shuffled list instead of modifying the original. This approach preserves your source data while generating a randomized copy.

  • The second argument len(original_list) specifies how many elements to sample. Using the full length creates a complete shuffled copy.
  • This method works well when you need both the original and shuffled versions simultaneously.
  • The function guarantees unique selections. Each element appears exactly once in the output list.

The output shows the original list remains unchanged at [1, 2, 3, 4, 5] while shuffled_list contains the same elements in a random order.

Implementing Fisher-Yates shuffle algorithm

import random
def fisher_yates_shuffle(arr):
    for i in range(len(arr)-1, 0, -1):
        j = random.randint(0, i)
        arr[i], arr[j] = arr[j], arr[i]
    return arr

my_list = [1, 2, 3, 4, 5]
print(fisher_yates_shuffle(my_list))
[3, 1, 4, 5, 2]

The Fisher-Yates algorithm systematically shuffles a list by working backwards from the last element. For each position i, it randomly selects an element from the remaining unshuffled portion and swaps it into place.

  • The range(len(arr)-1, 0, -1) creates a countdown from the last index to the first
  • Each iteration uses random.randint(0, i) to pick a random position from the unshuffled section
  • The selected element swaps with the current position using Python's multiple assignment: arr[i], arr[j] = arr[j], arr[i]

This approach ensures uniform randomness. Each element has an equal probability of ending up in any position. The algorithm modifies the list in place instead of creating a new copy—making it memory efficient for large datasets.

Using sorted() with a random key

import random
my_list = [1, 2, 3, 4, 5]
shuffled = sorted(my_list, key=lambda x: random.random())
print(shuffled)
[4, 2, 5, 1, 3]

This shuffling technique leverages Python's sorted() function with a custom key that assigns random values to each element. The key=lambda x: random.random() parameter generates a new random number between 0 and 1 for each comparison during sorting.

  • The lambda function creates a temporary random sorting value for each element
  • Since these random values change with each comparison, the final order becomes effectively random
  • This method creates a new list instead of modifying the original one

While this approach works for simple shuffling needs, it's less efficient than random.shuffle() because sorting algorithms require more comparisons. The method remains useful when you need both randomization and specific sorting logic in the same operation.

Advanced shuffling techniques

Building on the foundational shuffling methods, Python offers sophisticated techniques for weighted randomization, targeted list manipulation, and accelerated performance through specialized libraries like NumPy.

Weighted shuffling with different probabilities

import random
items = ['A', 'B', 'C', 'D']
weights = [0.1, 0.2, 0.5, 0.2]  # Probabilities for each item
weighted_shuffle = random.choices(items, weights=weights, k=len(items))
print(weighted_shuffle)
['C', 'C', 'B', 'D']

The random.choices() function enables weighted randomization, where some elements have a higher chance of selection than others. Each item in the list corresponds to a weight value that determines its probability of being chosen.

  • In this example, 'C' has a 50% chance (0.5) of being selected for each position
  • 'B' and 'D' each have a 20% chance (0.2)
  • 'A' appears least frequently with only a 10% chance (0.1)

The k parameter specifies how many selections to make. Setting it to len(items) creates a new list of the same length. Unlike basic shuffling, elements can appear multiple times in the output, making this method ideal for simulating probability-based events or creating weighted random distributions.

Partial shuffling of specific segments

import random
my_list = [1, 2, 3, 4, 5, 6, 7, 8]
start, end = 2, 6  # Shuffle only elements from index 2 to 5
sublist = my_list[start:end]
random.shuffle(sublist)
my_list[start:end] = sublist
print(my_list)
[1, 2, 5, 3, 4, 6, 7, 8]

Partial shuffling lets you randomize a specific portion of a list while keeping other elements in their original positions. The code extracts a segment using slice notation my_list[start:end], shuffles only that portion, then places it back into the original list.

  • The start index (2) marks where shuffling begins. The end index (6) defines where it stops
  • Python's slice assignment my_list[start:end] = sublist seamlessly reintegrates the shuffled segment
  • This technique proves useful when you need to preserve certain elements' positions while randomizing others

In the example output, only elements at indices 2 through 5 change positions. The first two elements (1, 2) and last two elements (7, 8) maintain their original order.

High-performance shuffling with NumPy

import numpy as np
arr = np.array([1, 2, 3, 4, 5])
shuffled_indices = np.random.permutation(len(arr))
shuffled_array = arr[shuffled_indices]
print(shuffled_array)
[3 1 5 2 4]

NumPy's array shuffling delivers superior performance compared to Python's built-in methods, especially for large datasets. The np.random.permutation() function generates a random sequence of indices, which we then use to reorder the original array.

  • The function creates a sequence from 0 to the array length (in this case, 0 to 4)
  • It randomly reorders these indices into a new permutation
  • NumPy's advanced indexing arr[shuffled_indices] efficiently creates the final shuffled array

This approach particularly shines when working with multidimensional arrays or when you need to maintain the same random order across multiple arrays. NumPy's vectorized operations make the process significantly faster than iterating through elements individually.

Get unstuck faster with Claude

Claude is an AI assistant from Anthropic that excels at helping developers write, debug, and understand code. It combines deep technical knowledge with natural conversation to provide clear, actionable guidance for programming challenges.

When you encounter tricky Python problems like optimizing shuffle algorithms or implementing custom randomization, Claude acts as your personal code mentor. It can explain complex concepts, suggest implementation approaches, and help you understand error messages or performance bottlenecks.

Start accelerating your Python development today. Sign up for free at Claude.ai to get instant help with code reviews, debugging, and technical questions.

Some real-world applications

Python's list shuffling capabilities power essential real-world applications, from simulating card games to preparing datasets for machine learning models.

Creating a simple card shuffler with random.shuffle()

The random.shuffle() function enables you to build a realistic card game simulator by randomly reordering a standard deck of playing cards—making it perfect for applications like poker or blackjack.

import random

suits = ['Hearts', 'Diamonds', 'Clubs', 'Spades']
ranks = ['A', 'K', 'Q', 'J', '10']
deck = [f"{rank} of {suit}" for suit in suits for rank in ranks]
random.shuffle(deck)
print(f"Shuffled deck: {deck[:3]}")

This code creates a partial deck of playing cards and randomly shuffles it. The suits and ranks lists contain the basic components of each card. A list comprehension combines these components, using string formatting to create cards like "A of Hearts" or "K of Spades".

The nested loop structure in [f"{rank} of {suit}" for suit in suits for rank in ranks] pairs each rank with each suit, generating all possible combinations. After shuffling with random.shuffle(), the code displays the first three cards using list slicing deck[:3].

  • The deck contains 20 cards total (4 suits × 5 ranks)
  • Each card appears exactly once in the deck
  • The output shows a random selection of three cards from the shuffled deck

Creating a randomized train-test split for machine learning

The random.shuffle() function enables effective dataset splitting for machine learning by randomly distributing data points between training and testing sets, ensuring unbiased model evaluation.

import random

data = [(x, x*2) for x in range(10)]
random.shuffle(data)

split_point = int(0.7 * len(data))
train_data, test_data = data[:split_point], data[split_point:]

print(f"Train: {train_data[:3]}...")
print(f"Test: {test_data}")

This code demonstrates data splitting for analysis or modeling. First, it creates a list of 10 tuples using a list comprehension, where each tuple contains a number and its double (like (0,0), (1,2), (2,4)). The random.shuffle() function then randomizes the order of these tuples.

The split ratio of 0.7 means 70% of the data goes to train_data and 30% to test_data. The split_point calculation determines the index where this division occurs. Python's slice notation data[:split_point] and data[split_point:] cleanly separates the shuffled data into two parts.

  • The final print statements show the first 3 training examples and all test examples
  • Shuffling ensures random distribution between sets
  • This technique helps prevent bias in data analysis

Common errors and challenges

Python's list shuffling can trigger unexpected errors when working with immutable types, string manipulation, or random number generation reproducibility.

Troubleshooting immutable sequences with random.shuffle()

The random.shuffle() function only works with mutable sequences like lists. Attempting to shuffle immutable sequences such as tuples triggers a TypeError. The following code demonstrates this common pitfall when working with Python's immutable data types.

import random
my_tuple = (1, 2, 3, 4, 5)
random.shuffle(my_tuple)  # This will raise TypeError
print(my_tuple)

The error occurs because random.shuffle() attempts to modify the sequence in place. Since tuples prevent modification after creation, Python raises a TypeError. Let's examine the corrected approach in the code below.

import random
my_tuple = (1, 2, 3, 4, 5)
my_list = list(my_tuple)
random.shuffle(my_list)
shuffled_tuple = tuple(my_list)
print(shuffled_tuple)

To shuffle immutable sequences like tuples, first convert them to a list using list(). After shuffling the list with random.shuffle(), convert it back to a tuple using tuple(). This approach preserves the immutability while allowing randomization.

  • Watch for this error when shuffling strings, tuples, or range objects
  • Remember that random.shuffle() always modifies sequences in place
  • Consider using random.sample() as an alternative for immutable sequences

The same principle applies when working with any immutable sequence type in Python. Always check if your data structure supports in-place modifications before attempting to shuffle it.

Shuffling strings with random.shuffle()

Strings in Python behave differently from lists when it comes to shuffling. The random.shuffle() function expects a mutable sequence that allows in-place modifications. Since strings are immutable sequences, attempting to shuffle them directly triggers a TypeError.

import random
my_string = "Python"
random.shuffle(my_string)  # This will raise TypeError
print(my_string)

The error occurs because random.shuffle() attempts to modify individual characters within the string "Python". Since Python strings don't allow character-level changes, the operation fails. The code below demonstrates the correct approach.

import random
my_string = "Python"
char_list = list(my_string)
random.shuffle(char_list)
shuffled_string = ''.join(char_list)
print(shuffled_string)

To shuffle a string, first convert it to a list of characters using list(). After shuffling with random.shuffle(), join the characters back together with ''.join() to create the final shuffled string.

  • Watch for this pattern when working with any immutable sequence that needs shuffling
  • The join() method efficiently concatenates characters without creating multiple intermediate strings
  • This approach works for both ASCII and Unicode strings

Remember that strings are immutable in Python. Any operation that appears to modify a string actually creates a new one instead.

Creating reproducible shuffles with random.seed()

Random shuffling in Python produces different results each time you run random.shuffle(). While this randomness proves useful for many applications, some scenarios require consistent, reproducible results. The code below demonstrates how shuffled sequences change between program runs.

import random
my_list = [1, 2, 3, 4, 5]
random.shuffle(my_list)
print("First shuffle:", my_list)
my_list = [1, 2, 3, 4, 5]
random.shuffle(my_list)
print("Second shuffle:", my_list)  # Different result each time

The code produces different random sequences with each execution because Python's random number generator starts from an unpredictable state. This makes testing and debugging challenging when you need consistent results. The following example demonstrates how to address this limitation.

import random
random.seed(42)  # Set a fixed seed
my_list = [1, 2, 3, 4, 5]
random.shuffle(my_list)
print("First shuffle:", my_list)
random.seed(42)  # Reset to same seed
my_list = [1, 2, 3, 4, 5]
random.shuffle(my_list)
print("Second shuffle:", my_list)  # Same result

Setting a fixed seed with random.seed() ensures your shuffled sequences remain consistent across program runs. The seed value (like 42) initializes Python's random number generator to produce the same sequence of random numbers each time. This reproducibility proves invaluable during testing, debugging, or when you need to validate results.

  • Always set the seed at the start of your program or function
  • Use different seed values to generate different but reproducible sequences
  • Remember that the same seed produces identical results only when the code runs in the same order

This technique particularly helps when debugging randomized algorithms or sharing code examples that rely on random operations. Just remember to remove or change the seed when you need true randomness in production.

Learning or leveling up? Use Claude

Claude combines deep technical expertise with natural language understanding to help you tackle Python programming challenges. Whether you're exploring list manipulation or building complex applications, Claude provides targeted guidance while explaining the reasoning behind its suggestions.

Here are some prompts you can use to get Claude's help with list shuffling:

  • Debug shuffling code: Ask "Why isn't this shuffle working: random.shuffle('hello')?" and Claude will explain string immutability and suggest using list() conversion
  • Performance optimization: Ask "How can I make this card shuffling code faster?" and Claude will recommend NumPy arrays or algorithm improvements
  • Implementation guidance: Ask "Show me how to shuffle only even numbers in a list" and Claude will provide a step-by-step solution with explanations
  • Conceptual understanding: Ask "What's the difference between random.shuffle() and random.sample()?" and Claude will clarify their distinct use cases

Experience Claude's capabilities firsthand by signing up for free at Claude.ai.

For seamless integration into your development workflow, try Claude Code to access AI assistance directly from your terminal. This powerful tool helps you write, review, and optimize code without leaving your preferred development environment.

FAQs

Additional Resources

How to find the length of an array in Python

2025-05-30
14 min
 read
Read more

Optimize code efficiency quickly with Claude

2025-05-30
6 min
 read
Read more

How to calculate a percentage in Python

2025-05-30
14 min
 read
Read more

Leading companies build with Claude

ReplitCognitionGithub CopilotCursorSourcegraph
Try Claude
Get API Access
Copy
Expand