How to shuffle a list in Python
Learn how to shuffle a list in Python. Explore different methods, tips, real-world applications, and common error debugging.

To shuffle a list in Python is a common task when you need to randomize data. Python's random module provides simple functions to reorder your list elements for various applications.
In this article, we'll cover several techniques to shuffle lists. We'll provide practical tips, review real-world applications, and offer advice to debug common issues you might encounter.
Using random.shuffle() for simple list shuffling
import random
my_list = [1, 2, 3, 4, 5]
random.shuffle(my_list)
print(my_list)--OUTPUT--[3, 5, 1, 4, 2]
The random.shuffle() function is the simplest way to randomize a list. It works by shuffling the list’s elements in place, which means it modifies the original my_list directly rather than creating and returning a new, shuffled list.
This in-place modification is memory-efficient because it avoids duplicating the list, a key advantage when you're working with large datasets. As the output demonstrates, the list now contains the same elements but in a completely random order.
Basic shuffling techniques
If modifying the original list isn't an option, Python provides alternative methods for creating a shuffled copy or implementing the shuffling logic from scratch.
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}")--OUTPUT--Original: [1, 2, 3, 4, 5]
Shuffled: [5, 2, 1, 3, 4]
When you need to keep your original list intact, random.sample() is the way to go. It returns a new, shuffled list without altering the source, which is perfect when you need to work with both the original and a randomized version of your data. As the output shows, original_list remains unchanged while shuffled_list holds the new random order.
- The function takes two arguments: the list you want to sample from and the number of items to select.
- By passing
len(original_list)as the second argument, you're telling it to create a new list containing all the original 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))--OUTPUT--[3, 1, 4, 5, 2]
Implementing the Fisher-Yates shuffle gives you a look under the hood of how randomization works. This classic algorithm shuffles a list in place, ensuring every possible permutation is equally likely.
- The code iterates backward from the end of the list.
- At each position
i, it swaps the current element with another element from a random positionj, from the start of the list up toi.
This process effectively randomizes the list by the time the loop finishes, modifying the original list directly.
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)--OUTPUT--[4, 2, 5, 1, 3]
You can also shuffle a list by using the sorted() function with a random key. This approach is a bit unconventional but effective, and it returns a new shuffled list without changing the original.
- The
keyargument is assigned alambdafunction that callsrandom.random()for each element. - This assigns a temporary random float to every item in the list.
sorted()then reorders the elements based on these random floats, producing a shuffled result.
Advanced shuffling techniques
Sometimes, simple shuffling isn't enough, and you'll need advanced techniques for applying weights, shuffling specific segments, or optimizing for large datasets.
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)--OUTPUT--['C', 'C', 'B', 'D']
When you need certain items to appear more often in a randomized list, you can use random.choices(). This function builds a new list by picking elements from the original based on probabilities you define. This method samples with replacement, so the resulting list isn't a true shuffle—it's a new random selection.
- The
weightsparameter assigns a probability to each corresponding element in your source list. - The
kparameter specifies the total number of items to choose for the new list. - Because it samples with replacement, elements can be chosen multiple times or left out entirely.
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)--OUTPUT--[1, 2, 5, 3, 4, 6, 7, 8]
If you need to randomize just a portion of a list, you can do so by isolating a segment. This is perfect for scenarios where you want to keep certain elements fixed while shuffling others. The process is straightforward and combines slicing with an in-place shuffle.
- First, you create a
sublistby slicing the original list with your desired range, likemy_list[start:end]. - Next, you apply
random.shuffle()directly to thissublist. - Finally, you assign the shuffled
sublistback to the original slice, updatingmy_listin place.
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)--OUTPUT--[3 1 5 2 4]
When you're working with large datasets, NumPy provides a significant performance boost. Its array operations are highly optimized, making them much faster than shuffling standard Python lists, especially as data size grows.
- The function
np.random.permutation()first generates a shuffled sequence of indices from 0 to the length of your array. - This new sequence is then used to create a shuffled copy of the original array by selecting elements in a random order—a technique known as fancy indexing.
This approach is efficient and creates a new shuffled array without altering the original.
Move faster with Replit
Replit is an AI-powered development platform where you can skip the setup and start coding instantly. It comes with all Python dependencies pre-installed, so you don't have to worry about environment configuration. While knowing individual techniques is useful, Agent 4 helps you move from learning concepts to building complete applications.
Instead of piecing together functions, you can describe the final product you want, and Agent 4 will build it:
- A quiz generator that randomizes the order of questions and answer choices using
random.shuffle(). - A giveaway tool that uses weighted probabilities to select winners, built with
random.choices(). - A playlist randomizer that shuffles songs but keeps specific tracks fixed, using partial shuffling techniques.
Simply describe your app, and Replit will write the code, test it, and fix issues automatically, all within your browser.
Common errors and challenges
Shuffling lists can lead to errors, particularly with immutable data types or when you need the same "random" order every time.
Troubleshooting immutable sequences. One of the most common pitfalls is trying to use random.shuffle() on an immutable sequence, like a tuple. Because random.shuffle() modifies the list in-place, it can't work on data types that can't be changed, and it'll raise a TypeError.
The fix is simple: convert the immutable sequence into a list before shuffling. You can then convert it back to a tuple if your program requires it.
Shuffling strings. Strings present a similar challenge because they are also immutable. To shuffle the characters in a string, you'll need to first convert it to a list. Once you shuffle that list, you can use the ''.join() method to stitch the characters back together into a new, randomized string.
Creating reproducible shuffles. Sometimes you need your "random" shuffle to be repeatable—especially for testing or debugging. You can achieve this by setting a starting point for the random number generator with random.seed(). By calling random.seed() with a specific integer before you shuffle, you guarantee the list will be shuffled into the exact same order every time that code runs.
Troubleshooting immutable sequences with random.shuffle()
Because random.shuffle() works by modifying a sequence in place, it runs into trouble with immutable data types like tuples. Trying to shuffle a tuple directly will raise a TypeError since its contents cannot be changed. Check out the code below to see this error in action.
import random
my_tuple = (1, 2, 3, 4, 5)
random.shuffle(my_tuple) # This will raise TypeError
print(my_tuple)
The TypeError occurs because random.shuffle() attempts an in-place modification on my_tuple, an immutable data type. See how to work around this limitation in the example 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 get around this limitation, you can temporarily convert the tuple to a list. This allows random.shuffle() to modify the sequence in place without errors. After shuffling the list, you simply convert it back into a tuple. This workaround is essential whenever you need to randomize an immutable sequence but must preserve the original data type for the rest of your program.
Shuffling strings with random.shuffle()
Since strings are immutable, you'll run into the same TypeError if you try to use random.shuffle() on them. The function can't alter the string's characters in place. The code below shows what happens when you try.
import random
my_string = "Python"
random.shuffle(my_string) # This will raise TypeError
print(my_string)
The code fails because random.shuffle() attempts to modify the string's internal character sequence, which isn't allowed. Check out the example below to see 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)
The solution is to convert the string into a list of its characters. This gives you a mutable sequence that random.shuffle() can work with. After shuffling the list, you simply use the ''.join() method to stitch the characters back together into a new, randomized string. This workaround is essential anytime you need to reorder characters, since strings themselves can't be altered directly in Python.
Creating reproducible shuffles with random.seed()
Creating reproducible shuffles with random.seed()
For testing or debugging, you often need a shuffle to be predictable. By default, random.shuffle() produces a different order each time, making it hard to replicate results. The code below shows how running the same shuffle twice yields different outcomes.
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 random.shuffle() function uses a different internal seed on every run, which explains the unpredictable outcomes. To get the same shuffled order every time for debugging, check out the following approach.
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
To make your shuffles predictable, call random.seed() with a fixed integer like 42 before shuffling. This sets the random number generator to a specific starting point, so random.shuffle() will produce the exact same "random" order every time. It's a crucial technique for debugging or writing tests where you need consistent results. Just remember to reset the seed and use the original list to get the same shuffle again.
Real-world applications
Beyond the technical methods, shuffling lists is a core part of building applications like card games and preparing machine learning data with vibe coding.
Creating a simple card shuffler with random.shuffle()
Shuffling a deck of cards is a classic use case for random.shuffle(), where you can generate a list of cards and then randomize their order with a single function call.
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 builds and shuffles a partial deck of cards. It uses a list comprehension with an f-string to efficiently combine every rank with every suit, creating the deck list. The random.shuffle() function then reorders this list in place.
- The nested
forloops within the list comprehension are key to generating all the card combinations. - Finally, slicing with
deck[:3]prints just the first three cards, showing a sample of the randomized deck.
Creating a randomized train-test split for machine learning
In machine learning, you can use random.shuffle() to randomize your entire dataset before splitting it, which helps prevent bias in your training and testing data.
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 a common data preparation technique. It first generates a list of tuples called data and then randomizes its order using random.shuffle().
- A variable,
split_point, is calculated to mark 70% of the dataset's length. - List slicing then divides the shuffled
datainto two new lists:train_datagets the first 70% of the items, andtest_datagets the remaining 30%.
This process effectively partitions your original dataset into two distinct, randomized subsets, a standard step before training a model.
Get started with Replit
Now, turn these techniques into a working tool. Describe what you want to Replit Agent, like “build a flashcard app that shuffles questions” or “create a workout generator that randomizes exercises.”
Replit Agent writes the code, tests for errors, and helps you deploy your application directly from your browser. Start building with Replit.
Describe what you want to build, and Replit Agent writes the code, handles the infrastructure, and ships it live. Go from idea to real product, all in your browser.
Describe what you want to build, and Replit Agent writes the code, handles the infrastructure, and ships it live. Go from idea to real product, all in your browser.



