我想要构造一个像随机数生成器一样工作的对象,但是按照指定的顺序生成数字。
# a random number generator
rng = lambda : np.random.randint(2,20)//2
# a non-random number generator
def nrng():
numbers = np.arange(1,10.5,0.5)
for i in range(len(numbers)):
yield numbers[i]
for j in range(10):
print('random number', rng())
print('non-random number', nrng())以上代码的问题,我不能在最后一行中调用nrng,因为它是一个生成器。我知道,重写上面代码的最简单的方法是简单地循环非随机数,而不是定义生成器。我更愿意让上面的例子起作用,因为我正在处理大量的代码,其中包括一个函数,它接受一个随机数生成器作为参数,并且我想在不重写整个代码的情况下添加传递非随机数序列的功能。
编辑:我在评论中看到了一些困惑。我知道python的随机数生成器会产生伪随机数。这篇文章是关于用一个数字生成器代替一个伪随机数生成器,该生成器从非随机用户指定的序列生成数字(例如,生成数字序列1,1,2,2,1,0,1的生成器,如果我愿意的话)。
发布于 2022-03-29 01:45:08
编辑:
要做到这一点,最干净的方法是使用lambda包装对next(nrng)的调用,这是@GACy20中的一个很好的注释:
def nrng_gen():
yield from range(10)
nrng = nrng_gen()
nrng_func = lambda: next(nrng)
for i in range(10):
print(nrng_func())原来的答案:
如果您希望您的对象保持状态,并且看起来像一个函数,请使用__call__方法创建一个自定义类。
例如:
class NRNG:
def __init__(self):
self.numbers = range(10)
self.state = -1
def __call__(self):
self.state += 1
return self.numbers[self.state]
nrng = NRNG()
for i in range(10):
print(nrng())但是,除非绝对必要,否则我不建议这样做,因为它掩盖了nrng保持状态的事实(尽管从技术上讲,大多数rng都在内部保持状态)。
最好通过调用next来使用带有yield的常规生成器,或者编写自定义迭代器(也是基于类的)。这些工具将适用于类似for循环和其他用于迭代的python工具(比如优秀的itertools包)。
发布于 2022-03-29 00:42:17
您可以使用生成器或迭代器调用next()作为参数,从其中提取一个元素。预先将生成器保存到变量允许您多次执行此操作。
# make it a generator
def _rng():
while True:
yield np.random.randint(2,20)//2
# a non-random number generator
def _nrng():
numbers = np.arange(1,10.5,0.5)
for i in range(len(numbers)):
yield numbers[i]
rng = _rng()
nrng = _nrng()
for j in range(10):
print('random number', next(rng))
print('non-random number', next(nrng))发布于 2022-03-29 00:52:00
np.random.randint可以记住它生成的最后一个数字,因为它是np.random.RandomState类的函数。Numpy只是对类方法进行化名,这样就可以从np.random模块直接访问它,而不是让您通过类访问它。
知道了这一点,您可以编写自己的类,如下所示:
class NotRandom:
numbers = np.arange(1,10.5,0.5)
last_index = -1
@classmethod
def nrng(cls):
cls.last_index += 1
if cls.last_index < len(cls.numbers):
return cls.numbers[cls.last_index]
# else:
return None
# Create an alias to the classmethod
nrng = NotRandom.nrng # Note this is OUTSIDE the class然后,你可以:
print(nrng()) # 1.0
print(nrng()) # 1.5
print(nrng()) # 2.0如果您希望能够拥有多个并发nrng实例,则可以使nrng()成为实例方法,而不是类方法:
class NotRandom:
def __init__(self):
self.numbers = np.arange(1,10.5,0.5)
self.last_index = -1
def nrng(self):
self.last_index += 1
if self.last_index < len(self.numbers):
return self.numbers[self.last_index]
# else:
return None
# Create an object. Then create an alias to its method
nrng = NotRandom().nrng 然后,您可以使用nrng()来引用绑定到您创建的NotRandom实例的方法。如果您想要另一个实例,您也可以这样做:
another_notrandom = NotRandom()
nrng2 = another_notrandom.rng
print(nrng()) # 1.0
print(nrng()) # 1.5
print(nrng2()) # 1.0
print(nrng()) # 2.0
print(nrng2()) # 1.5https://stackoverflow.com/questions/71655179
复制相似问题