0

I'm trying to create a code that produces a list of 5 different random number. Here is my current code:

import random

rN0 = random.randint(1, 50)
rN1 = random.randint(1, 50)
rN2 = random.randint(1, 50)
rN3 = random.randint(1, 50)
rN4 = random.randint(1, 50)

randomNumber = [rN0, rN1, rN2, rN3, rN4]

But, sometimes it produces two or more of the same number in the list. I would like each number in the list to be unique every time. Help please?

martineau
  • 119,623
  • 25
  • 170
  • 301
Lili
  • 9
  • 2

3 Answers3

1

You can use random.sample that picks n random numbers from a given range:

>>> random.sample(range(1, 50), 5)
[4, 41, 16, 40, 25]
Selcuk
  • 57,004
  • 12
  • 102
  • 110
0

Here is a function to do just that:

import random
def difRandom(min,max,amount):
  li=[]
  if amount>max+1-min:
    raise Exception("Not enough random numbers to cover amount. \nPlease increase max or decrease min.")
  for x in range(0,amount):
    r=random.randint(min,max)
    while r in li:
      r=random.randint(min,max)
    li.append(r)
  return(li)

All numbers will be different.

[Edit]

New function that is better:

def difRandom(min,max,amount):
  li=[x for x in range(min,max+1)]
  final=[]
  if amount>max+1-min:
    raise Exception("Not enough random numbers to cover amount. \nPlease increase max or decrease min.")
  random.shuffle(li)
  for y in range(0,amount):
    final.append(li[y])
  return(final)

This function above is a bit quicker, and doesn't have to wait for the random.randint to get it right.

Agent Biscutt
  • 712
  • 4
  • 17
  • Note that the time complexity of such methods cannot be computed. It has the potential to be an endless loop. – Selcuk Oct 13 '21 at 00:15
  • Not so, the raise error stops that from being case of a user error. However, I do agree that there is a slight chance, however small, that the random generator never generates a number to fill in the list. That is an extremely small chance though, and I have a feeling the random generator will generate the number before too long. – Agent Biscutt Oct 13 '21 at 00:18
  • True, but I was talking about the behaviour of the `random` function. `randint` can return the "wrong" number for a very long time. Compare the performance of `difRandom(1, 100000, 100000)` with `random.sample`. – Selcuk Oct 13 '21 at 00:22
  • 1
    Yeah, true. The other way I could do it is generate a list of all the numbers in range, and then take a random out of those, deleting the random index every time. It would create an ever shortening list that never returns the some value, and doesn't have the same time problems. – Agent Biscutt Oct 13 '21 at 00:25
  • This is a well researched subject. Look up "Fisher-Yates shuffle" if you are interested. – Selcuk Oct 13 '21 at 00:26
  • @Selcuk You act like your `random.sample` usage didn't have the exact same "problem"... – no comment Oct 13 '21 at 00:35
  • @don'ttalkjustcode Well, because it doesn't. Care to elaborate? – Selcuk Oct 13 '21 at 00:38
  • @Selcuk , I have provided a solution in my edit, can you see any problems? Please tell me if you can. – Agent Biscutt Oct 13 '21 at 00:40
  • @Selcuk It does pretty much [the exact same thing](https://github.com/python/cpython/blob/854db7e82126701f2bf7a3ca0d78e3e26096aa75/Lib/random.py#L496-L503) here (except storing selected indexes in a set instead, but that's irrelevant for that "endless loop" issue). – no comment Oct 13 '21 at 00:41
  • @don'ttalkjustcode The part you highlighted is only executed if `k` is relatively small when compared to `n`. See [this comment](https://github.com/python/cpython/blob/854db7e82126701f2bf7a3ca0d78e3e26096aa75/Lib/random.py#L439-L444). – Selcuk Oct 13 '21 at 00:51
  • @Selcuk As they are in your usage. I checked. – no comment Oct 13 '21 at 00:52
  • @don'ttalkjustcode It looks like you just want to nit pick and don't really want to have a technical argument. This is not the right place. – Selcuk Oct 13 '21 at 00:53
  • @AgentBiscutt Your second method is much faster as `shuffle` is `O(n)`. That being said, `random.sample` has a few more optimisations under the hood as can be seen from the source code linked above but your method is just fine for all practical purposes. – Selcuk Oct 13 '21 at 00:55
  • @Selcuk Your k would btw be even relatively smaller if you used the correct n (i.e., the correct range). – no comment Oct 13 '21 at 00:56
  • @Selcuk Ok, so [2.35 seconds is "much faster" than 0.53 seconds](https://tio.run/##zVLBasMwDL3nK0RPMc1CszIYhey26xi7diW4id0IbDm4zpZ@fWc7ydoNyq4LBFvSe0/ys7uTaw2tHzt7PqPujHVgOTVGJ42Q0KB8i1GRaqRM8yHj2vTk2CYBUFhud35FCWP2yQOWxZ2HhjJ4JTwKeB5q0Tk0lC5ejANBpj@0UxegXu@FPYIzUJsPYSelHN7pVQnu6Ui1jRsvDsZCI@YYKV8w30j67OBxQfMg0tX1jH6IcmyVhwXJzSdhsfrZohJgA1vhSPiLojDnXSeoSW1IWOF6S6lC9tOy@1uWDb8HnnDLggU3JRJX/8PYyYVj20upRDzi6Pbppttx@tkfhdvT7sqjWGRJIq0f0KEW6GB6dGOUBPHqIr6eVX1a9lSHyuVNZldmz1cH4KCc1FLF9b7hm0hNPfxh5X@WTd6UxSp87JvZ2XDXLov4vKqIa1FVY32ssfP5Cw). Good to know. – no comment Oct 13 '21 at 01:10
-1

You can use the below given code for this purpose :-

import random

#This code supposes that you need to generate 10 random integers.

randomNumber = random.sample(range(1, 50), 10)

#This function returns a list of random numbers within a given range 
#The second parameter tells how many random numbers to generate for the list
Utkarsh
  • 105
  • 4