无需导入 'random' 的随机 int

问题描述 投票:0回答:5

有没有办法让程序在不导入的情况下选择 1 到 1,000 之间的随机数

random

python python-3.x random
5个回答
12
投票

基于

random
源代码

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

您还可以使用PRNG

实现
random_bytes()


4
投票

有许多有趣的方法可以生成随机性,而无需诉诸随机(或 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

1
投票

假设你想要整数。

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

0
投票
#method one, set new seed every time random is needed


seed = "seed" #can be int or string, varies between compilings of the game
possibilities = 3 #0,1,2

hash(str(seed))%possibilities

hash(str(0))%3 #single random number between 0,1,2 (inc) seed is 0


#method two, generate a random list of numbers


size = 100 #length of list
possibilities = 2 #0,1

[hash(str(seed))%possibilities for seed in range(size)]

[hash(str(seed))%5 for seed in range(100)] #generates a list of numbers between 0,1,2,3,4 (inc) with the size of 100
hash(" ")%6


[hash(str(seed))%2 for seed in range(100)].count(1) #validity check. output is ~50

我编写这个程序来帮助解决这个问题


0
投票

幸运的是,我所处的环境恰好已经有可用的日期时间。日期时间通常需要导入,因此这不能解决没有任何导入的问题(我认为OP正在解决这个问题)

而且,让我们明确一点,这不是一个真正的随机数,但对于许多实际应用来说它已经足够接近了。

int( str( datetime.now().microsecond )[-1] ) 
# yields a number from 0 through 9

int( str( datetime.now().microsecond )[-2:] ) 
# yields a number from 0 through 99
© www.soinside.com 2019 - 2024. All rights reserved.