Skip to main content

How to Generate Unique Random Numbers Within a Range in Python

Generating a set of unique random numbers within a specific range is a common requirement in various applications, such as simulations, sampling, or creating unique identifiers.

This guide explores efficient and reliable methods for achieving this in Python, using random.sample(), random.shuffle(), and NumPy. We'll also cover how to exclude specific numbers from the generated range.

The random.sample() function is the most direct and Pythonic way to get a list of unique random numbers from a range:

import random

def gen_unique_random_numbers(low, high, n):
# range(low, high) goes up to, but DOES NOT include, high
return random.sample(range(low, high), n)

# Get 5 unique random numbers between 1 (inclusive) and 10 (exclusive)
print(gen_unique_random_numbers(1, 10, 5)) # Output (example): [6, 9, 4, 8, 1]
print(gen_unique_random_numbers(1, 10, 5)) # Output (example): [8, 4, 1, 3, 5]
  • range(low, high) creates the sequence of numbers to sample from.
  • random.sample(population, k) returns a new list containing k unique elements chosen randomly from the population.
  • This method ensures uniqueness (no duplicates) and is generally efficient.
warning

random.sample() will raise a ValueError if n (the number of samples requested) is larger than the number of elements in the range (high - low). Handle this with a try...except block if necessary:

try:
result = random.sample(range(1, 5), 5)
except ValueError as e:
print(f"Error: {e}") # Output: Error: Sample larger than population or is negative

Generating Unique Random Numbers with random.shuffle()

An alternative approach involves creating the full list of numbers, shuffling it randomly, and then taking the first N elements:

import random

def gen_unique_random_shuffle(low, high, n):
number_list = list(range(low, high)) # Create the full list
random.shuffle(number_list) # Shuffle the list in-place
return number_list[:n] # Take the first n elements

print(gen_unique_random_shuffle(1, 10, 5)) # Output: [5, 7, 9, 3, 6]
print(gen_unique_random_shuffle(1, 10, 5)) # Output: [9, 4, 6, 3, 8]
  • This method works well but can be less memory-efficient than random.sample() for very large ranges, as it requires creating the entire list in memory first.

Generating Unique Random Numbers with NumPy

If you are already using the NumPy library, numpy.random.choice() provides a convenient way to generate unique random numbers:

import numpy as np

# Generate 6 unique random numbers between 1 (inclusive) and 15 (exclusive)
unique_numbers = np.random.choice(
range(1, 15),
6, # Number of samples to generate
replace=False # Ensure uniqueness (no replacement)
).tolist() # Convert NumPy array back to a Python list

print(unique_numbers) # Output: [13, 14, 9, 6, 11, 12]
  • Important: Set replace=False to guarantee unique elements. The default is True (allowing duplicates).
  • Install NumPy if needed: pip install numpy

Generating Random Numbers Excluding Specific Values

To generate random numbers within a range while excluding certain numbers:

Using List Comprehension and random.choice()

Create a list containing only the allowed numbers, then pick randomly from that list:

from random import choice

def gen_random_excluding(low, high, exclude):
allowed_numbers = [num for num in range(low, high) if num not in exclude]
if not allowed_numbers: # Handle case where all numbers are excluded
return None # Or raise an error
return choice(allowed_numbers)

numbers_to_exclude = [1, 3, 7]
print(gen_random_excluding(1, 10, numbers_to_exclude)) # Output: 2
  • The list comprehension creates a new list with all the numbers that should not be excluded.
  • random.choice() picks one element from the filtered list.

Using Sets and random.choice()

Using set difference can be more efficient for larger ranges or exclusion lists:

from random import choice

def gen_random_excluding_set(low, high, exclude):
full_set = set(range(low, high))
exclude_set = set(exclude)
allowed_set = full_set - exclude_set # Set difference
if not allowed_set:
return None # Or raise an error
return choice(list(allowed_set)) # Convert back to list for choice

numbers_to_exclude = [1, 3, 7]
print(gen_random_excluding_set(1, 10, numbers_to_exclude)) # Output: 4
  • Set difference (-) efficiently finds elements present in the full_set but not in the exclude_set.

Conclusion

This guide demonstrated several reliable ways to generate unique random numbers within a specified range in Python.

  • random.sample() is the most direct and generally recommended method for standard Python lists.
  • random.shuffle() provides an alternative, while numpy.random.choice(..., replace=False) is ideal if you're working with NumPy arrays.
  • When needing to exclude specific numbers, filtering the range using list comprehensions or set operations before making a random choice are effective strategies.