milesabc123
milesabc123

Reputation: 85

List Comprehensions method to generate a sequence of random and unique numbers

I am writing a programme to generate 6 numbers (lotto style). I want to then generate a second number and compare the two and see how long it takes (in terms of counts) before the two sets of numbers match.

This is my code :

import random

range_of_numbers = [i for i in range(1,60)]

def draw_a_ticket():
    total_numbers = range_of_numbers = [i for i in range(1,60)]
    draw = []
    i = 0
    while i < 6:
        num = random.choice(total_numbers)
        total_numbers.remove(num)
        draw.append(num)
        i += 1
    return draw

draw = draw_a_ticket()
draw1 = draw_a_ticket()
counter = 0
while draw[0:2] != draw1[0:2]: # I am using [0:2] to reduce the complexity/find match sooner
    counter += 1
    draw = draw1
    draw1 = draw_a_ticket()

print(f"{counter} : Draw:{draw} - Draw1:{draw1}")

The code above works fine. But I am trying to be more pythonic and use list comprehensions to generate the numbers sets.

Ive tried the following - but I get an invalid syntax:

draw = [i = set(random.randint(1,60)) in range(1,7)]
print(draw)

The key features I am trying to achieve in a list comprehension is to:

  1. generate 6 unique random integers between 1 and 59
  2. store these in a list.

Thanks for any help.

Upvotes: 1

Views: 770

Answers (3)

TheEagle
TheEagle

Reputation: 5980

Your second approach is fine, except for that you are trying to do assignment in a list comprehension and converting an int from random.randint to a set. Your draw_ticket function should be like this:

def draw_ticket():
    numbers = list(range(0, 60)) # no need for a list comprehension to get a list from a
                                 # range - just convert it directly
    draw = [numbers.pop(numbers.index(random.choice(numbers))) + 1 for n in range(6)]
    return draw

Above code is not easy to understand (as most list comprehensions), so I made an easy-to-understand-version below:

def draw_ticket():
    numbers = list(range(0, 60))
    draw = []
    for n in range(6): # iterate 6 times
        index = numbers.index(random.choice(numbers))                               
        number = numbers.pop(index)
        draw.append(number)
    return draw

So that's what the above list comprehension does.

Upvotes: 0

milesabc123
milesabc123

Reputation: 85

Thanks to everyone who responded, really appreciated the suggestions. Ive kind of pieced all the answers together and come up with a version of the programme that doesn't use the function but seems to work ok:

import random

draw = list(set([(random.randint(1,60)) for i in range(1,7)]))
draw1 = list(set([(random.randint(1,60)) for i in range(1,7)]))
counter = 0
while draw[0:2] != draw1[0:2]: # using [0:2] reduces the complexity
    counter += 1
    draw = draw1
    draw1 = list(set([(random.randint(1,60)) for i in range(1,7)]))

print(f"{counter} : Draw:{draw} - Draw1:{draw1}")

Thanks again.

Upvotes: 0

Belhadjer Samir
Belhadjer Samir

Reputation: 1669

for your question generate 6 unique random integers between 1 and 59 and store them in list you can use random.sample()

Return a k length list of unique elements chosen from the population sequence or set. Used for random sampling without replacement.

try this :

draw=random.sample(range(1,59),6)

for all your program you can do it like this :

import random

def draw_a_ticket():
    return random.sample(range(1,60),6)

draw = draw_a_ticket()
draw1 = draw_a_ticket()
counter = 0
while draw[0:2] != draw1[0:2]: # I am using [0:2] to reduce the complexity/find match sooner
    counter += 1
    draw = draw1
    draw1 = draw_a_ticket()

print(f"{counter} : Draw:{draw} - Draw1:{draw1}")

if you want your program select draw only once you can append the generated draw to a list of selected draws :

like this :

import random

selected_draw=[]
def draw_a_ticket():
    draw=random.sample(range(1,60),6)
    if draw in selected :
        draw_a_ticket()
    selected_draw.append(draw)
    return draw

draw = draw_a_ticket()
draw1 = draw_a_ticket()
counter = 0
while draw[0:2] != draw1[0:2]: # I am using [0:2] to reduce the complexity/find match sooner
    counter += 1
    draw = draw1
    draw1 = draw_a_ticket()

print(f"{counter} : Draw:{draw} - Draw1:{draw1}")

Upvotes: 2

Related Questions