随机int而不导入随机'

时间:2014-04-09 00:36:46

标签: python python-3.x random import

有没有办法让程序选择1到1,000之间的随机数而不导入'随机'?

非常感谢帮助。

3 个答案:

答案 0 :(得分:5)

基于random source code

def randint(a, b):
    "Return random integer in range [a, b], including both end points."
    return a + randbelow(b - a + 1)

def randbelow(n):
    "Return a random int in the range [0,n).  Raises ValueError if n<=0."
    if n <= 0:
       raise ValueError
    k = n.bit_length()
    numbytes = (k + 7) // 8
    while True:
        r = int.from_bytes(random_bytes(numbytes), 'big')
        r >>= numbytes * 8 - k
        if r < n:
            return r

def random_bytes(n):
    "Return n random bytes"
    with open('/dev/urandom', 'rb') as file:
        return file.read(n)

示例:

print(randint(1, 1000))

你也可以implement random_bytes() using PRNG

答案 1 :(得分:3)

有许多有趣的方法可以生成随机性,而无需求助于 random(或 numpy)。例如,您可以使用内置的哈希函数:

def rand_generator(seed, N=10**6, a=0, b=10, integer = True):
    '''For a given seed, this function returns N pseudo-random between a and b'''
    rands =[]
    if integer:
        for i in range(N):
            num = int(a+(b-a)*(abs(hash(str(hash(str(seed)+str(i+1)))))%10**13)/10**13)
            rands.append(num)
        return rands
    else:
        for i in range(N):
            num = a+(b-a)*(abs(hash(str(hash(str(seed)+str(i+1)))))%10**13)/10**13
            rands.append(num)
        return rands

这将生成一个介于 0 和 1 之间的均匀分布的伪随机数列表。就像 random 和 numpy 中的随机数生成器一样,对于给定的种子,序列是完全确定的。

Histogram of the function's output.

该算法在加密方面绝不是安全的,但它应该足以回答您的问题。

如果不希望存储整个列表,那么同样的想法可以采用生成器表达式的形式。如上所述设置 a、b、N 和种子的值后:

randnum = (int(a+(b-a)*(abs(hash(str(hash(str(seed)+str(j+1))))) % 10**13)/ 10**13) for i in range(N))

是一个迭代器,通过

生成序列中的下一个数字
>>> next(randnum)
    5

这可以做得更整洁,如下所示:

def random(seed = None, a=0, b=10,  N=10**12, integer=True):
    '''Pass a seed to generate new sequence, otherwise next value is returned.'''
    if seed:
        print("Starting new sequence.")
        global _rand_generator 
        if integer: 
            hash_plus = lambda j: int(a + (b-a)*(abs(hash(str(hash(str(seed) + str(j+1))))) % 10**13)/ 10**13)
        else:
            hash_plus = lambda j: a + (b-a)*(abs(hash(str(hash(str(seed) + str(j+1))))) % 10**13)/ 10**13
        _rand_generator =  (hash_plus(j) for j in range(N))
    try:
        return next(_rand_generator)
    except:
        print("Random seed required.")
            

要生成随机序列,请将种子传递给函数。

>>> random(42)
Starting new sequence.
    8 

在没有种子的情况下再次调用该函数以产生序列中的下一个随机数/整数。

>>> for i in range(10): 
...     print(random())
    3
    4
    6
    5
    5
    9
    2
    2
    4
    0

要开始一个新序列,只需使用新种子再次调用该函数即可。

>>> random(666)
Starting new sequence.
    5

答案 2 :(得分:0)

假设你想要整数。

import numpy as np
np.random.randint(1,1000)