1

Suppose I want to generate a bunch of binary number generators given the success probabilities. One concern I have is about the random seed. The random seeds for f1, f2, f3 are their creation time, right? And the seeds are fixed for each function regardless of the random seed in the global namespace, right?

def f(p):
    import random, time
    random.seed(time.time())
    def g():
        return 1 if random.random() < p else 0
    return g

f1 = f(0.05)
f2 = f(0.65)
f3 = f(0.25)
10
  • 1
    There's only one random module and therefore only one seed. You'll have to create a random.Random(seed) object for each function. Commented Mar 15, 2017 at 1:20
  • Seeding a bunch of random number generators with the same seed is not very random. Commented Mar 15, 2017 at 1:23
  • @rici That's exactly my concern. Commented Mar 15, 2017 at 1:40
  • @Rawing That's why I'm importing random in the decorator, not out of it. No help? Commented Mar 15, 2017 at 1:41
  • But why do you feel the need to have multiple PRNG streams? All your generators can happily share a single PRNG, no? Commented Mar 15, 2017 at 2:39

1 Answer 1

3

You pass in a seed to the global random object each time you call f(), because all top-level functions in the random module feed into a singleton object. This means that by the time f3 is created, the seeds set in f2 and f1 have been superseded, the seeds are not independent from the global random object. Importing random again for each f() call does not give you a new state, as really only binds names anew each time once the module object itself is loaded (only on the first import).

If you want to have a seeded random generator per function, you need to create individual random.Random() instances:

import random
import time

def f(p):
    seeded_random = random.Random(time.time())
    def g():
        return 1 if seeded_random.random() < p else 0
    return g

From the random module documentation:

The functions supplied by this module are actually bound methods of a hidden instance of the random.Random class. You can instantiate your own instances of Random to get generators that don’t share state.

Sign up to request clarification or add additional context in comments.

12 Comments

Are you saying f1, f2, f3 have the same random seed at the end? Suppose I only return random.random() in function g, then I would see the same values from f1, f2 and f3? A bit confused, please help make further clarification. Thanks.
@Maxareo: no, you won't see the same values. But in your code, f1, f2 and f3 all use a single global Random() object. You tell that one object to use a new seed three times, which simply means you discard whatever state was set for the first two calls.
@Maxareo: after that, f1, f2 and f3 produce random numbers from that one global Random() object seeded to the last call. That means they'll produce values in the same sequence as if you used one random.Random() object with the same seed as that last random.seed() call.
@Maxareo: those numbers are still pseudorandom. If you took a foo = random.Random(seed_foo) object, then called foo.random() a number of times, the values that that produces can be re-created exactly by using the exact same seed again in a different random.Random() object. Your f1, f2 and f3 simply draw from that sequence together, they are not backed by independent random.Random() objects. Their state is connected.
Thanks for the replies. These are indeed helpful. The part that is puzzling me is the modules are imported inside the function and how is the random seed related to the function g? When f1, f2 and f3 are created, they don't have their own random seed? Besides, I tried a little example importing the random module inside a toy function, run the toy function and called random.random() in the global namespace, but didn't work.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.