random.random
The building block of the module: uniform, triangular, choices and every distribution start from random(). It can return 0.0 but never 1.0, and every result is an exact multiple of 2**-53.
Common call
random.random()
Returns
float in [0.0, 1.0)
Replaces
Math.random() in JavaScript, rand() / RAND_MAX in C
Watch out
Not for security; for ints use randint, not int(random() * n)
random.random()
→ float
Demo
Live evaluation
Seed the generator and draw three floats. Every one is at least 0.0 and below 1.0.
Try:
Inputs
seedint | stran int or a string
Code
import random random.seed(42) [random.random() for _ in range(3)]
Result
[0.6394267984578837, 0.025010755222666936, 0.27502931836911926]
With seed 42 the first float is 0.6394267984578837: times 10 that is 6.394267984578837 and int() keeps 6. Times -10, int() truncates -6.394267984578837 toward zero, giving -6, not -7. The probability tab compares the same six floats with p, so raising p can only turn False into True.
Common patterns
Do something with probability p
True about p of the time.
import random if random.random() < 0.05: log_debug_sample(request)
A float in [a, b)
What uniform(a, b) computes.
import random x = a + (b - a) * random.random()
Jitter for retries
Randomize back-off delays so clients do not retry in lockstep.
import random import time time.sleep(base_delay * (1 + random.random()))
Examples
1. Three floats after seeding
import random
random.seed(42)
[random.random() for _ in range(3)]
Returns
[0.6394267984578837, 0.025010755222666936, 0.27502931836911926]2. Always below 1.0
import random
random.random() < 1.0
Returns
True3. Scale to [5, 10)
import random
random.seed(42)
lo, hi = 5.0, 10.0
lo + (hi - lo) * random.random()
Returns
8.197133992289424. Events with probability 0.5
import random
random.seed(42)
[random.random() < 0.5 for _ in range(6)]
Returns
[False, True, True, True, False, False]5. An exact multiple of 2**-53
import random
random.seed(42)
x = random.random()
x * 2 ** 53 == int(x * 2 ** 53)
Returns
True6. Round for display
import random
random.seed(42)
round(random.random() * 100, 2)
Returns
63.947. It takes no arguments
import random
random.random(5)
Returns
TypeError: Random.random() takes no arguments (1 given)Pitfalls
1. Calling the module
After import random, the name random is the module; the function is random.random. (from random import random binds the function instead.)
random()
import random random()
TypeError: 'module' object is not callable. Did you mean: 'random.random(...)'?
random.random()
import random random.seed(42) random.random()
0.6394267984578837
2. int(random() * n) for dice
Scaling gives 0 to n-1, never n, so a "die" built this way shows 0 and never 6. randint(1, 6) includes both ends and draws from getrandbits, so the sequence is also different.
int(random() * 6)
import random random.seed(42) [int(random.random() * 6) for _ in range(10)]
[3, 0, 1, 1, 4, 4, 5, 0, 2, 0]
randint(1, 6)
import random random.seed(42) [random.randint(1, 6) for _ in range(10)]
[6, 1, 1, 6, 3, 2, 2, 2, 6, 1]
When to use
Use it
- Probabilities: random() < p
- A raw uniform float to transform yourself
- Jitter, sampling rates, randomized thresholds
Reach for something else
- Integers → randint / randrange (exactly uniform, no float rounding)
- A float in another range → uniform(a, b)
- Anything secret → secrets
Notes
CPython impl
Modules/_randommodule.c random_random: a = genrand_uint32() >> 5 (27 bits), b = genrand_uint32() >> 6 (26 bits), result (a * 67108864.0 + b) * (1.0 / 9007199254740992.0), i.e. (a * 2**26 + b) / 2**53
Resolution
Only the 2**53 evenly spaced multiples of 2**-53 can occur; many other floats in [0, 1), such as most values below 2**-53, are never produced
Stability
The docs guarantee random() keeps producing the same sequence for the same seed in future versions
FAQ
No. The result is (a * 2**26 + b) / 2**53 with a below 2**27 and b below 2**26, so the largest possible value is 1 - 2**-53 = 0.9999999999999999. 0.0 is possible (about one chance in 2**53).