user2462068
user2462068

Reputation: 161

Python Random's with no repeats

Here is my code, im trying to fill a list with 7 numbers between 0-6 with no duplicates, and a random order every time. Here is my code but I keep getting an error "list assignment index out of range", I don't see where my error is though. Here is my code:

    import random
def generate():
    listA = []
    for x in range(0,6):
        listA[x] = random.sample(range(6), 1)
generate()
print(listA)

Upvotes: 2

Views: 1479

Answers (3)

Luis Masuelli
Luis Masuelli

Reputation: 12333

You can use random.shuffle.

list_ = list(range(7)) #a list from 0 to 6. list() not needed in Python 2
shuffle(list_)
print(list_)

However, if your shuffled list is big, you should consider:

Note that for even rather small len(x), the total number of permutations of x is larger than the period of most random number generators; this implies that most permutations of a long sequence can never be generated.

And so you should manually implement it:

yourlist = range(1000) #or a bigger number, or an arbitrary list
yournewlist = []
for i in range(len(yourlist)):
    yournewlist.append(yourlist.pop(random.randint(0, len(yourlist)-1)))

Notice I calculate len(yourlist) N+1 times. This value should be never stored in a variable. The first calculation defines the iteration (in Python 2, you could use xrange instead of range for the count iteration). The following iterations will have a different value of len(yourlist) (from N to 1). Remember that randint(lowerBound, uppweBound) will include upperBound, so you should ALWAYS use 0 and the length - 1 to get a valid list index. This constrasts to many other languages like Pascal which do not include the upperBound value among the expected results for integer random functions.

Remember: both the algorithm I described AND the use os shuffle alter the original list. My alg. puts the result in a distinct list.

Upvotes: 1

g.d.d.c
g.d.d.c

Reputation: 47988

It'd be more effective to just shuffle the result of range.

>>> from random import shuffle
>>>
>>> r = range(7)
>>> shuffle(r)
>>> r
[5, 3, 6, 4, 1, 0, 2]

Note that in Python 3 you have to explicitly convert r to a list:

>>> r = list(range(7))

Upvotes: 5

abarnert
abarnert

Reputation: 365717

To assign an element past the end of a list, use listA.append(…).

What you're trying to do is replace the value for a slot that doesn't exist, which is why you get an IndexError.

Also, I'm pretty sure you just wanted listA = random.sample(range(6), 6). What you've written just does 6 separate 1-element samplings, with no repeats in each sampling.

(Alternatively, you could just write listA = range(6) then random.shuffle(listA).)

Upvotes: 0

Related Questions