2

so what I am trying to do is create a list of 5 numbers for the game mastermind, and I would like to eliminate all duplicates! The issue is that the code sometimes creates a list with 3 numbers, or 4, or sometimes 5, it seems to be random.

I should also mention we are not allowed to be usin grandom.sample, or random.shuffle

import random

def generatePassword() :
    lis = []
    for i in range(5) :
        #This checks to see if there are duplicate numbers
        r = random.randint(1,9)
        if r not in lis :
            lis.append(r)
        i+=1
    return lis



def main() :
    print(generatePassword())
main()
3
  • 2
    If you want to use that approach, you need to keep going until the list has 5 elements, not just try to add a value 5 times. (Also, i+=1 doesn’t do anything – range(5) is already taking care of providing the values 0, 1, 2, 3, 4 in sequence. Also also, random.sample.) Commented Nov 1, 2018 at 16:18
  • It's because you only append when the randomly selected integer isn't in the list. In addition to appending the unique integers, you should also have some condition for when the randomly generated integer is already in the list. Commented Nov 1, 2018 at 16:19
  • Ahhh yeah of course, thanks! Changed to a while loop instead Commented Nov 1, 2018 at 16:24

6 Answers 6

8

Use numpy.random.permutation if you are looking for method that works and is faster:

import numpy as np
your_list = list(np.random.permutation(np.arange(0,10))[:5])

>>> your_list
[6, 9, 0, 1, 4]

Alternatively, you can use np.random.choice with replace=False:

your_list = list(np.random.choice(np.arange(0,10), 5, replace=False)
Sign up to request clarification or add additional context in comments.

4 Comments

numpy is a bit overkill for random.sample(range(1, 10), 5).
@Ry- Yes. but it will scale better if OP desires so.
But what if the range is from 0 to a million, and OP only wants 5 numbers? Isn't it a waste to permute all one million possible values just to select five of them?
@Kevin You're right, I did a test, and random.sample was much faster. I'll keep this answer for info only.
4

Try using a while loop with a condition that checks for the length of lis

while len(lis) < 5:

instead of your for loop

4 Comments

Bless your soul. This worked. Totally didn't think of len(list)
This works but could be slow; it has to keep running this code till it gets 5, which (theoretically) could take forever.
Yeah, "theoretically". But it won't. Python modules are extremely fast, and can run a loop hundreds of thousands of times a second. If he wanted to add 999,999 unique numbers to a list out of 1,000,000, it could take forever, but since he is just needs 5 out of 10, it won't take long at all.
@SanguineL: Good point. It makes no sense worrying for speed when it takes only couple of microseconds to finish the task like this
3

The function random.sample does what you want:

import random

def generatePassword():
    numbers = range(0, 9)
    return random.sample(numbers, 5)

def main() :
    print(generatePassword())
main()

3 Comments

I should have mentioned we're not allowed to use random.sample, thanks though!
@SpencerVreugdenhil-Beauclerc While homework/classwork questions are allowed, please make it clear that that is what they are, as well as restrictions.
@ArtemisFowl I am sorry! I should have mentioned that in my post, for sure will next time!
2

You don't want to add random, unique integers 5 times; you want to add random, unique integers until your list contains 5 elements. This'll do it:

import random

def generatePassword() :
    lis = []
    while len(lis) < 5:
        #This checks to see if there are duplicate numbers
        r = random.randint(1,9)
        if r not in lis :
            lis.append(r)
    return lis

Comments

2

I do not recommend the solution in this answer - the best option in the standard library is probably random.sample, and there may be more efficient methods using numpy. Both of these options are suggested in other answers.


This method uses random.shuffle to shuffle a list of digits, then selects the first five. This avoids the issue of a theoretically unbounded loop (while len(nums) < 5:), but does not scale well when the range of numbers to choose from (here, 1 to 9) is significantly larger than how many numbers are needed (here, 5).

import random

population = list(range(1, 10))
random.shuffle(population)
print(population[:5])

3 Comments

That's certainly the most efficient way, but since he already had most of the code needed, while len(lis) < 5: works too.
@SanguineL See my comment on your answer
@SanguineL Not your answer, sorry, Pallie's answer
1

So your problem: It won't add the same number twice. But since you use a for i in range(5): it will only repeat 5 times, regardless of if it added a unique number or not.

You need to measure the length of the list, so it will always add 5 random, unique numbers to the list.

You have the code mostly right, but all you need to do is replace: for i in range(5): with: while len(lis) < 5:

Make sure to delete the i += 1 though. It will cause an error if you don't.

Here's the code:

import random

def generatePassword() :
    lis = []
    while len(lis) < 5:
        #This checks to see if there are duplicate numbers
        r = random.randint(1,9)
        if r not in lis :
            lis.append(r)
    return lis



def main() :
    print(generatePassword())
main()

2 Comments

IMO this is the best answer because it explains what the OP did wrong.
Thanks for the feedback!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.