generators : random shootout
Mark McEahern
marklists at mceahern.com
Tue Jan 15 17:27:29 EST 2002
GerritM wrote:
> can this instead be replaced by:
>
> for i in gen_random(100.0): pass
Short answer: No.
Why not?
1. Calling the generator returns an iterator. You need to call the
iterator, not the generator:
gr = gen_random(100.0)
for i in gr:pass
2. If you call it this way, the proposed solution will not StopIteration,
so you have an infinite loop.
3. You can add a counter parameter to the generator:
def gen_random(max, N):
n = 0
last = 42 # initialize
while n < N: # test the counter
n = n + 1 # increment the counter
last = (last * IA + IC) % IM # update prior value
rand = max * last / IM # generate the random number
yield rand # yield it
However, now you won't be able to display the last value.
**
Below is the solution I ended up with, in case you'd like to tinker with it.
As the shootout site stated, the solution should generate 8.163294467 for N
= 1000.
Cheers,
// mark
#! /usr/bin/env python
# gen2.py
# based on: http://www.bagley.org/~doug/shootout/
from __future__ import generators
import sys
IM = 139968 # modulo
IA = 3877 # multiplier
IC = 29573 # increment
def gen_random(max):
last = 42 # initialize
while 1: # this generator can be called
indefinitely
last = (last * IA + IC) % IM # update prior value
rand = max * last / IM # generate the random number
yield rand # yield it
def main():
try:
N = int(sys.argv[1])
except IndexError:
N = 1000
if N < 1:
N = 1
gr = gen_random(100.0)
for i in xrange(1, N):
gr.next()
print "%.9f" % gr.next()
import time
timeIn = time.time()
main()
timeOut = time.time()
print "%f seconds." % (timeOut - timeIn)
More information about the Python-list
mailing list