如何在Python中拒绝随机数字

2024-09-29 23:31:39 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图建立一个彩票号码生成器,但我不知道如何使随机模块重播号码,如果已经生成或属于一个名单。 所以基本上我希望旧的数字不再被生成。抱歉,如果我不够明确,但我把代码留在这里。谢谢

import random

oldNumbers = [5, 11, 19, 20, 38]

ball1 = random.randint(1, 39)
ball2 = random.randint(1, 39)
ball3 = random.randint(1, 39)
ball4 = random.randint(1, 39)
ball5 = random.randint(1, 39)

print(ball1, ball2, ball3, ball4, ball5)

Tags: 模块代码import数字random号码randint名单
3条回答

下面是一个简单的解决方案:

print(random.sample([i for i in range(1, 39) if i not in oldNumbers], 5))

或者您可以简单地使用set减法:

print(random.sample(set(range(1, 39)) - set(oldNumbers), 5))

Selcuk's answer是解决您的问题的最佳方法,但我认为我应该提供一种替代方法,当range很大,而oldNumbers不太大时,这种方法会更有效。你知道吗

from itertools import islice
from random import sample

forbidden = set(oldNumbers)

numneeded = 5

# Might have old numbers in it, but definitely has at least 5 new numbers
numbers = random.sample(range(1, 39), numneeded + len(forbidden))

# Generates only the new numbers
notForbidden = (num for num in numbers if num not in forbidden)

# Keep only as many as you need
newNumbers = list(islice(notForbidden, numneeded))

所有这些(除了导入)都可以是一行(newNumbers = list(islice(filterfalse(set(forbidden).__contains__, random.sample(range(1, 39), 10)), 5))),但我将其拆分以供说明。你知道吗

这样做的好处是不需要构造一个经过过滤的list来传递给sample,如果range变大,可能会成为运行时/内存的问题。取而代之的是,你只需要生成足够的数字,你就可以确定你至少已经生成了你需要的数量,即使你碰巧选择了所有禁止的数字,然后只保留需要的数量。你知道吗

Selcuk的答案是O(n)range的大小,这个答案是O(n)你需要生成的数加上要排除的数(由于明显的原因,它应该总是小于range的大小)。你知道吗

有两条捷径。第一种方法是两个随机数多次尝试并拒绝列表中的随机数

import random
oldNumbers = [5, 11, 19, 20, 38]
for i in range(5):
    ball=random.randint(1, 39)
    while ball in oldNumbers:
        print('Rejected:',ball)
        ball = random.randint(1, 39)
    print(oldNumbers,ball)
    oldNumbers+=[ball]

另一种方法是只从包含所需数字的列表中选择随机数字。你知道吗

import random
oldNumbers = [5, 11, 19, 20, 38]
for i in range(5):
    newNumbers = [i for i in range(1,39) if i not in oldNumbers]
    ball=random.choice(newNumbers)
    print(oldNumbers,ball)
    oldNumbers+=[ball]

相关问题 更多 >

    热门问题