Written and maintained by CASRAI Editorial Board
Last updated
numpy.random.randint returns random integers from a discrete uniform distribution on the half-open interval [low, high): the low value can appear, the high value never does. Its signature is numpy.random.randint(low, high=None, size=None, dtype=int). The same function is also written numpy random randint in searches, and it is one of the legacy functions NumPy now steers new code away from in favour of Generator.integers.
What randint is used for in research
Researchers reach for randint whenever an analysis needs random whole numbers: drawing row indices for a bootstrap resample, assigning participants to numbered arms of a simulated trial, generating integer-valued test data, or picking random positions in an array. For sampling items from an existing list or array, numpy random choice is usually the more direct tool; randint is the right one when you want integers from a numeric range.
Two things make randint easy to misuse, and they are the focus of this guide: the upper bound is excluded, and the default integer type depends on the platform. The NumPy documentation also flags the function as part of the legacy RandomState API, so this guide shows the modern equivalent next to each example.
Install or access
NumPy’s own install page lists these routes. With pip:
pip install numpy
With conda (from the defaults or conda-forge channels):
conda create -n my-env
conda activate my-env
conda install numpy
The same page recommends working inside a virtual environment: python -m venv my-env, then activate it (source my-env/bin/activate on macOS and Linux, my-env\Scripts\activate on Windows) before running pip install numpy. Then import it:
import numpy as np
Step-by-step: generate random integers with randint
- Draw one integer from [0, low). If you pass a single argument, it is treated as the exclusive upper bound and the range starts at 0:
np.random.randint(5)returns one Pythonintfrom 0 to 4. - Set both bounds.
np.random.randint(1, 7)returns an integer from 1 to 6, becausehighis one above the largest integer that can be drawn. This is the usual die-roll pattern. - Ask for many values with
size.np.random.randint(2, size=10)returns an array of ten values, each 0 or 1. A tuple gives a shape:np.random.randint(5, size=(2, 4))returns a 2 by 4 array of integers in [0, 5). With the defaultsize=None, a single value is returned. - Use arrays for per-element ranges.
lowandhighmay be array-like and are broadcast against each other.np.random.randint(1, [3, 5, 10])draws three values, the first from [1, 3), the second from [1, 5) and the third from [1, 10).np.random.randint([1, 5, 7], 10)varies the lower bound instead. - Choose the type with
dtype. The documentation’s own example combines broadcasting and a type:np.random.randint([1, 3, 5, 7], [[10], [20]], dtype=np.uint8)returns a 2 by 4 array of unsigned 8-bit integers. - Make the run repeatable. The legacy functions share one global generator, seeded with
np.random.seed. On NumPy 2.5.1,np.random.seed(0)followed bynp.random.randint(1, 7, size=5)returned[5 6 1 4 4]. NumPy states that the legacyRandomStatecontinues to use the MT19937 algorithm and that old seeds continue to reproduce the same results.
The modern equivalent: randint vs Generator.integers
The randint documentation says: “New code should use the integers method of a Generator instance instead.” The page does not mark the function deprecated, and the NumPy random-generation overview says there are no plans to remove the legacy functions, so existing code keeps working. The signature of the replacement is Generator.integers(low, high=None, size=None, dtype=np.int64, endpoint=False).
import numpy as np
rng = np.random.default_rng(seed=20261029) # any large positive integer
rng.integers(1, 7, size=5) # same half-open range as randint(1, 7, size=5)
rng.integers(1, 6, size=5, endpoint=True) # closed range: 1 to 6 inclusive
The mapping is direct. RandomState.randint corresponds to integers with endpoint=False, and the old random_integers (closed interval [low, high]) corresponds to integers with endpoint=True. A seeded default_rng produces the same stream every time you create it with the same seed, but the stream is different from the one np.random.seed gives, so switching APIs changes the numbers in an existing analysis. NumPy’s guidance on seeds is to use large, unique positive integers; default_rng accepts positive integers of any size. These generators are designed for statistical modelling and simulation, not for security or cryptography.
Output and how to read it
Is the high value included?
No. randint(low, high) samples from [low, high). If you want 6 to be possible, pass 7, or use rng.integers(1, 6, endpoint=True).
What type comes back?
A call with no size returns a Python int; a call with size returns an ndarray. The default dtype=int is the C long. The documentation warns that this is 32 bits on Windows and 64 bits on 64-bit Linux and macOS, and that since NumPy 2.0 the default integer elsewhere in NumPy is np.intp, so dtype=int here does not behave like int in most other NumPy functions. If your range, or later arithmetic on the results, could exceed 32-bit limits, pass an explicit type such as dtype=np.int64. Generator.integers defaults to np.int64, which removes the platform difference.
How to generate a 2D array of random integers
Pass a tuple to size: np.random.randint(0, 10, size=(3, 4)) returns a 3 by 4 array. The result is random, so your numbers will differ unless you seed.
Troubleshooting
ValueError: low >= high. The interval is empty. On NumPy 2.5.1,np.random.randint(5, 5)raised exactly this error. Remember thathighis exclusive, so equal bounds leave nothing to draw.ValueError: high is out of bounds for uint8. The requested range does not fit the chosen type. On the same version,np.random.randint(0, 300, dtype=np.uint8)raised this error. Pick a widerdtypeor a smaller range.- Different results on another machine. Check the default integer type (see above) and whether the run is seeded. Setting
dtypeexplicitly removes the first cause. - Results change between runs. Without a seed, the numbers differ on every run. Seed the generator when you need a repeatable analysis, and record the seed.
Free alternatives
| Function | Package | Range it samples |
|---|---|---|
numpy.random.randint(low, high) |
NumPy (legacy API) | [low, high): high excluded |
Generator.integers(low, high) |
NumPy (recommended for new code) | [low, high) by default; [low, high] with endpoint=True |
random.randint(a, b) |
Python standard library | a <= N <= b: both ends included; an alias for randrange(a, b+1) |
random.randrange(start, stop) |
Python standard library | Selects from range(start, stop, step), so stop is excluded |
The standard-library random.randint has the same name as the NumPy function but the opposite endpoint rule, a common source of off-by-one errors when code is moved between the two. NumPy’s functions return arrays directly, which matters for large simulations; for the wider toolkit, see numpy zeros for pre-allocating result arrays, numpy unique for counting what you drew and numpy repeat for building repeated index patterns.
FAQ
Is the high value included in numpy randint?
No. The interval is half-open, [low, high). Use endpoint=True with Generator.integers for a closed interval.
Is numpy random randint deprecated?
The documentation does not mark it deprecated. It belongs to the legacy RandomState API, and NumPy recommends that new code use Generator.integers. The overview page says there are no plans to remove the legacy functions.
How do I get an inclusive range?
Add one to high in randint, or call rng.integers(low, high, endpoint=True).
How do I generate a 2D array of random integers?
Give size a tuple, for example size=(2, 4).
How do I make randint reproducible?
Seed the legacy generator with np.random.seed(n), or create np.random.default_rng(n) and call integers on it.
Sources
- NumPy documentation, numpy.random.randint (checked 2026-10-29).
- NumPy documentation, numpy.random.Generator.integers (checked 2026-10-29).
- NumPy documentation, Random sampling (numpy.random) (checked 2026-10-29).
- NumPy, Installing NumPy (checked 2026-10-29).
- Python documentation, random: generate pseudo-random numbers (checked 2026-10-29).







