377

I know how to generate a random number within a range in Python.

random.randint(numLow, numHigh) 

And I know I can put this in a loop to generate n amount of these numbers

for x in range (0, n): listOfNumbers.append(random.randint(numLow, numHigh)) 

However, I need to make sure each number in that list is unique. Other than a load of conditional statements, is there a straightforward way of generating n number of unique random numbers?

The important thing is that each number in the list is different to the others..

So

[12, 5, 6, 1] = good

But

[12, 5, 5, 1] = bad, because the number 5 occurs twice.

1

4 Answers 4

600

If you just need sampling without replacement:

>>> import random >>> random.sample(range(1, 100), 3) [77, 52, 45] 

random.sample takes a population and a sample size k and returns k random members of the population.

If you have to control for the case where k is larger than len(population), you need to be prepared to catch a ValueError:

>>> try: ... random.sample(range(1, 2), 3) ... except ValueError: ... print('Sample size exceeded population size.') ... Sample size exceeded population size 
Sign up to request clarification or add additional context in comments.

6 Comments

Using random.sample(xrange(1, 100), 3) - with xrange instead of range - speeds the code a lot, particularly if you have a big range, since it will only generate on-demand the required 3 numbers (or more if the sampling without replacement needs it), but not the whole range. For example: %timeit random.sample(xrange(10000), 3) = 4.92 µs per loop, %timeit random.sample(range(10000), 3) = 126 µs per loop
If you're using Python2, yes. If you're using Python 3 as in my answer it's already doing this because xrange -> range in Py3k.
We, could instead of enclosing the random.sample() call inside the try...except block, check if the size of the sample (3 above) is smaller or equal (<=) than the size of the population (range(1, 2) above).
@h4k1m You can but in general EAFP (try/except) is stylistically preferred to LBYL (if/else) in Python.
3 can be replaced with randint(1, N)
|
33

Generate the range of data first and then shuffle it like this

import random data = list(range(numLow, numHigh)) random.shuffle(data) print data 

By doing this way, you will get all the numbers in the particular range but in a random order.

But you can use random.sample to get the number of elements you need, from a range of numbers like this

print random.sample(range(numLow, numHigh), 3) 

1 Comment

To shuffle a range in python 3 you first need to cast it to a list: data = list(range(numLow, numHigh)), otherwise you will get an error.
16

You could add to a set until you reach n:

setOfNumbers = set() while len(setOfNumbers) < n: setOfNumbers.add(random.randint(numLow, numHigh)) 

Be careful of having a smaller range than will fit in n. It will loop forever, unable to find new numbers to insert up to n

1 Comment

If you use random.sample it will throw a ValueError for that case (which of course you can catch).
10

You could use the random.sample function from the standard library to select k elements from a population:

import random random.sample(range(low, high), n) 

In case of a rather large range of possible numbers, you could use itertools.islice with an infinite random generator:

import itertools import random def random_gen(low, high): while True: yield random.randrange(low, high) gen = random_gen(1, 100) items = list(itertools.islice(gen, 10)) # Take first 10 random elements 

After the question update it is now clear that you need n distinct (unique) numbers.

import itertools import random def random_gen(low, high): while True: yield random.randrange(low, high) gen = random_gen(1, 100) items = set() # Try to add elem to set until set length is less than 10 for x in itertools.takewhile(lambda x: len(items) < 10, gen): items.add(x) 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.