List Comprehensions 方法生成一系列随机且唯一的数字

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

我正在编写一个程序来生成 6 个号码(乐透式)。然后我想生成第二个数字并比较这两个数字,看看在两组数字匹配之前需要多长时间(就计数而言)。

这是我的代码:

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}")

上面的代码工作正常。但我正在尝试变得更加pythonic并使用列表推导来生成数字集。

我试过以下 - 但语法无效:

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

我试图在列表理解中实现的主要功能是:

  1. 生成 6 个介于 1 和 59 之间的唯一随机整数
  2. 将这些存储在列表中。

感谢您的帮助。

针对您的问题生成 6 个介于 1 和 59 之间的唯一随机整数并将它们存储在列表中您可以使用 random.sample()

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

试试这个:

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

对于您的所有程序,您都可以这样做:

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}")

如果您希望您的程序 select 只绘制一次,您可以将生成的绘制附加到 selected 绘制列表中:

像这样:

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}")

你的第二种方法很好,除了你试图在列表理解中进行赋值并将 int 从 random.randint 转换为 set。你的 draw_ticket 函数应该是这样的:

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

上面的代码不太容易理解(因为大多数列表理解),所以我在下面做了一个易于理解的版本:

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

这就是上面的列表理解所做的。

感谢所有回复的人,非常感谢您提出的建议。 我把所有的答案拼凑在一起,想出了一个不使用该功能但似乎工作正常的程序版本:

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}")

再次感谢。