The random module in the Python standard library generates pseudo-random numbers and makes random selections from sequences. Use it for simulations, games, shuffling data, and sampling, or any task where you want values you cannot predict.
The module uses the Mersenne Twister algorithm, which is fast and produces high-quality randomness for non-security purposes. For passwords, authentication tokens, or cryptographic keys, use the secrets module instead.
import random
print(random.random()) # 0.7248319562104832
print(random.randint(1, 10)) # 7random.random() returns a float from 0.0 up to but not including 1.0. random.randint(1, 10) returns a random integer between 1 and 10, including both endpoints, and your exact values will differ on every run.
Random floats
Three functions cover most needs for random floating-point numbers, from flat ranges to bell curves. Like everything else in the Python standard library, they are ready to use the moment you import the module.
import random
print(random.random()) # 0.3847192048561034
print(random.uniform(2.5, 5.5)) # 3.9281047518294476
print(random.gauss(mu=0, sigma=1)) # -0.5128374019263847random.random() always stays between 0.0 and 1.0. random.uniform picks a float between the two bounds you give it, and random.gauss draws from a normal distribution with the given mean and standard deviation.
Use uniform when you need a random float in a specific range. Use gauss when modeling natural variation, like heights in a population or measurement errors.
Random integers
Use randint for inclusive ranges and randrange when you want a step between the possible values.
import random
print(random.randint(1, 6)) # 4
print(random.randrange(0, 100, 5)) # 65random.randint(1, 6) works like a die roll and can return any integer from 1 to 6, with both endpoints included. random.randrange(0, 100, 5) picks from 0, 5, 10, and so on up to 95. The third argument is the step, just like the built-in range function, and the stop value is excluded.
Pick random items from a sequence
Use choice to select one item, and choices when you want to allow repeats in the selection.
import random
colors = ["red", "green", "blue", "yellow"]
print(random.choice(colors)) # blue
print(random.choices(colors, k=3)) # ['yellow', 'red', 'green']random.choice picks a single element from the list. random.choices picks k elements and may return the same element more than once, because it selects with replacement.
You can also pass weights to bias the selection toward certain items:
import random
colors = ["red", "green", "blue", "yellow"]
picks = random.choices(colors, weights=[10, 1, 1, 1], k=5)
print(picks) # ['red', 'red', 'green', 'red', 'red']Here "red" is ten times more likely to be picked than any other color. The weights list must be the same length as the sequence you are choosing from.
When repeats are not acceptable, such as dealing cards or drawing lottery numbers, switch to random.sample, which selects without replacement:
import random
deck = list(range(1, 53))
hand = random.sample(deck, k=5)
print(sorted(hand)) # [3, 14, 27, 31, 48]random.sample returns 5 unique numbers, like drawing cards from a shuffled deck. The original list is unchanged, and k must not exceed the length of the sequence.
Shuffle a list in place
random.shuffle reorders a list randomly and modifies it directly instead of returning a new list.
import random
cards = ["A", "K", "Q", "J", "10"]
random.shuffle(cards)
print(cards) # ['Q', 'A', '10', 'K', 'J']The call changes the order of the cards list in place and returns None. If you need to keep the original order, make a copy first, or use random.sample with k set to the full length of the list.
Reproducible randomness with seed
By default the module produces different values on every run. When you are debugging, testing, or running an experiment that must be repeatable, set a seed first.
import random
random.seed(42)
print(random.random()) # 0.6394267984578837
print(random.randint(1, 100)) # 4
random.seed(42)
print(random.random()) # 0.6394267984578837
print(random.randint(1, 100)) # 4Calling random.seed(42) resets the generator to a fixed starting point, so the same calls produce the same results every time. Any integer, string, float, or bytes value works as a seed. Reproducible sequences are invaluable when comparing algorithm runs or chasing a bug.
Use secrets for security-sensitive values
The random module is not safe for security, because its output is predictable to an attacker who observes enough of it. For passwords, tokens, and session IDs, import secrets instead.
import secrets
token = secrets.token_hex(16)
print(token) # a7f3c09e1b2d4588f6e04c3179a25bf3secrets.token_hex(16) produces a cryptographically secure random string of 32 hexadecimal characters. The secrets module draws from the operating system's secure random source, which makes it safe for authentication and encryption work.
Practical example: dice rolling simulator
Combining a few of these functions produces a small, useful program. This one rolls a die with any number of sides, any number of times, and checks for a natural 20.
import random
def roll_dice(sides=6, count=1):
return [random.randint(1, sides) for _ in range(count)]
results = roll_dice(sides=20, count=4)
print("D20 rolls:", results) # D20 rolls: [17, 3, 14, 20]
print("Highest:", max(results)) # Highest: 20
if 20 in results:
print("Critical hit!") # Critical hit!The roll_dice helper is a regular Python function that builds its result with randint inside a list comprehension. The final check looks for a 20 anywhere in the results and celebrates the critical hit.
Common mistakes
Watch for these three mistakes when using the module.
Calling shuffle on a tuple or string. random.shuffle works in place, so it only accepts mutable sequences like lists. Convert the sequence to a list first:
import random
directions = ("north", "south", "east", "west")
items = list(directions)
random.shuffle(items)
print(items) # ['east', 'north', 'west', 'south']The list call turns the tuple into a mutable list, which shuffle can then reorder without raising an error.
Using random for security. Always use secrets for tokens, passwords, and anything cryptographic. The random module is for simulations, games, and other non-security randomness.
Forgetting that choices allows repeats. random.choices can pick the same item multiple times. If you need unique items, use random.sample instead.
Rune AI
Key Insights
- Use
random.random()for floats between 0.0 and 1.0. - Use
random.randint(a, b)for random integers including both endpoints. - Use
random.choice(seq)to pick one item andrandom.choices(seq, k=n)with weights for biased picks. - Use
random.sample(seq, k)to pick unique items without replacement. - Use
random.shuffle(list)to reorder a list in place. - Use
random.seed(n)to reproduce the same random sequence. - For security-sensitive randomness, use the
secretsmodule instead ofrandom.
Frequently Asked Questions
Is Python's random module safe for passwords?
What does random.seed() do?
How do I get a random float between two numbers?
Conclusion
The random module covers most everyday randomness needs: picking items, shuffling sequences, generating numbers, and making weighted selections. Remember to use secrets instead of random when you are generating passwords, tokens, or anything security-sensitive. Use seed() to make your random results reproducible for testing.
More in this topic
Format Dates and Times in Python
Learn how to use strftime and strptime to format dates as strings and parse date strings into Python datetime objects.
What Is the Python Standard Library?
Learn what the Python standard library is, why it matters, and how to use its built-in modules without installing anything extra.
Encode and Decode Base64 Data in Python
Learn how to use Python's base64 module to encode binary data as text and decode Base64 strings back to bytes.