Ali*_*rze 18 python generator python-3.x
我想构造一个像随机数生成器一样工作的对象,但以指定的顺序生成数字。
# 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())
Run Code Online (Sandbox Code Playgroud)
上面代码的问题是我无法nrng
在最后一行调用,因为它是一个生成器。我知道重写上面代码的最直接方法是简单地循环非随机数而不是定义生成器。我更喜欢让上面的示例工作,因为我正在处理大量代码,其中包含一个接受随机数生成器作为参数的函数,并且我想添加传递非随机数字序列而不重写的功能整个代码。
编辑:我在评论中看到一些混乱。我知道 python 的随机数生成器生成伪随机数。这篇文章是关于用一个数字生成器替换伪随机数生成器,该数字生成器从非随机的、用户指定的1,1,2,2,1,0,1
序列生成数字(例如,如果我想要的话,可以生成数字序列的生成器)。
Gre*_*Guy 20
您可以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))
Run Code Online (Sandbox Code Playgroud)
Mar*_*cin 16
编辑:
最简洁的方法是使用 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())
Run Code Online (Sandbox Code Playgroud)
原答案:
如果您希望对象保持状态并看起来像函数,请使用__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())
Run Code Online (Sandbox Code Playgroud)
然而,除非绝对必要,否则我不会推荐这样做,因为它掩盖了你的 nrng 保持状态的事实(尽管从技术上讲,大多数 rng 在内部保持其状态)。
最好通过yield
调用 next 来使用常规生成器或编写自定义迭代器(也是基于类的)。这些将与 for 循环和其他用于迭代的 python 工具(如优秀的 itertools 包)一起使用。
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
Run Code Online (Sandbox Code Playgroud)
然后,你可以这样做:
print(nrng()) # 1.0
print(nrng()) # 1.5
print(nrng()) # 2.0
Run Code Online (Sandbox Code Playgroud)
如果您希望能够有多个并发实例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
Run Code Online (Sandbox Code Playgroud)
然后,您可以使用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.5
Run Code Online (Sandbox Code Playgroud)
\n\n接受随机数生成器作为参数的函数
\n
那么就这样称呼它:
\nthat_function(nrng().__next__)\n
Run Code Online (Sandbox Code Playgroud)\n或者与functools.partial
:
that_function(partial(next, nrng()))\n
Run Code Online (Sandbox Code Playgroud)\n或者没有你的发电机,如果这arange
就是你想要的:
that_function(iter(np.arange(1,10.5,0.5)).__next__)\n
Run Code Online (Sandbox Code Playgroud)\n演示代码(rng
是nrng
你的,我添加了that_function
测试调用):
import numpy as np\nfrom functools import partial\n\n# a random number generator\nrng = lambda : np.random.randint(2,20)//2\n\n# a non-random number generator\ndef nrng():\n numbers = np.arange(1,10.5,0.5)\n for i in range(len(numbers)):\n yield numbers[i]\n\ndef that_function(rng):\n print(*(rng() for j in range(10)))\n\nthat_function(rng)\nthat_function(nrng().__next__)\nthat_function(iter(np.arange(1,10.5,0.5)).__next__)\nthat_function(partial(next, nrng()))\n
Run Code Online (Sandbox Code Playgroud)\n输出(在线尝试!):
\n4 6 1 3 8 7 3 6 2 1\n1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0 5.5\n1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0 5.5\n1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0 5.5\n
Run Code Online (Sandbox Code Playgroud)\n
归档时间: |
|
查看次数: |
3990 次 |
最近记录: |