あなたは見てみたいrandom.getstate()
とrandom.setstate()
。これを生成されたアイテムの数を追跡することと組み合わせると、やりたいことを行うのは非常に簡単です。
random
これに依存している場合は、他のコードの使用に注意する必要があることに注意してください。そのrandom.Random()
ため、これを回避するために使用するインスタンスを作成することをお勧めします。
このモジュールによって提供される関数は、実際には、random.Randomクラスの非表示インスタンスのバインドされたメソッドです。ランダムの独自のインスタンスをインスタンス化して、状態を共有しないジェネレーターを取得できます。
(ドキュメントから)
実装例:
from itertools import islice
import collections
from random import Random
def consume(iterator, n):
"Advance the iterator n-steps ahead. If n is none, consume entirely."
# Use functions that consume iterators at C speed.
if n is None:
# feed the entire iterator into a zero-length deque
collections.deque(iterator, maxlen=0)
else:
# advance to the empty slice starting at position n
next(islice(iterator, n, n), None)
class RewindRandom:
def __init__(self):
self._random = Random()
self._state = self._random.getstate()
self._count = 0
def __iter__(self):
while True:
yield self._random.random()
def __call__(self):
self._count += 1
return next(iter(self))
def rollback(self, amount):
self._random.setstate(self._state)
consume(self, self._count-amount)
self._count -= amount
これは次のように使用できます。
random = RewindRandom()
>>> random()
0.31276818768213244
>>> random()
0.7031210824422215
>>> random()
0.7196351574136909
>>> random.rollback(2)
>>> random()
0.7031210824422215
>>> random()
0.7196351574136909
>>> random()
0.6582894948982371