如何拒绝python中的随机数?

时间:2019-01-10 01:08:47

标签: python python-3.x python-2.7

我尝试构建彩票号码生成器,但是我不知道如何使随机模块重放已经生成或属于列表的号码。 因此,基本上,我希望不再生成oldNumbers中的数字。抱歉,如果我不够明确,但是我将代码留在这里。谢谢

add

3 个答案:

答案 0 :(得分:5)

这是一个简单的解决方案:

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

答案 1 :(得分:0)

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

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]

答案 2 :(得分:0)

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的大小。