[英]how do I reject random numbers in python?
我尝试构建彩票号码生成器,但是我不知道如何使随机模块重播已生成的号码或属于列表的号码。 因此,基本上,我希望不再生成oldNumbers中的数字。 抱歉,如果我不够明确,但是我将代码留在这里。 谢谢
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)
这是一个简单的解决方案:
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))
有两种简单的方法。 第一个是两次尝试多次随机数并拒绝列表中的那些
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]
Selcuk的答案是解决您问题的最佳方法,但是我认为我会提供一种替代方法,当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))
( newNumbers = list(islice(filterfalse(set(forbidden).__contains__, random.sample(range(1, 39), 10)), 5))
)但我拆分以进行说明。
这样做的好处是不需要构造一个经过过滤的list
来传递给sample
,如果range
变大,可能会成为运行时间/内存问题。 相反,您只需生成足够的数字,就可以确保至少生成了所需的数量,即使您碰巧选择了所有禁止的数字,然后仅保留所需的数量即可。
其中Selcuk的答案是O(n)
是range
的大小,此答案是O(n)
,即您需要生成的数字数加上要排除的数字(为了确定,该数字应始终小于range
的大小原因)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.