15

In Python, what is the best way to generate some random number using a certain seed but without reseeding the global state? In Java, you could write simply:

Random r = new Random(seed);
r.nextDouble();

and the standard Math.random() would not be affected. In Python, the best solution that I can see is:

old_state = random.getstate()
random.seed(seed)
random.random()
random.setstate(old_state)

Is this idiomatic Python? It seems much less clean than the Java solution that doesn't require "restoring" an old seed. I'd love to know if there's a better way to do this.

Sophie Alpert
  • 139,698
  • 36
  • 220
  • 238

1 Answers1

30

You can instantiate your own Random object.

myrandom = random.Random(myseed)

The random module manages its own instance of Random, which will be unaffected by changes made to myrandom.

senderle
  • 145,869
  • 36
  • 209
  • 233
  • Oops, somehow I missed this comment on the [random docs](http://docs.python.org/library/random.html): "You can instantiate your own instances of Random to get generators that don’t share state." Thanks! – Sophie Alpert Jun 17 '12 at 20:33
  • 2
    @BenAlpert, yeah, I did too when I went to double-check them. But I knew that I had seen `Random` in `dir(random)` before, and it was there in the source when I looked. Not sure why the `Random` class itself doesn't have its own listing in the docs. – senderle Jun 17 '12 at 20:35
  • It's always amazing to me when someone gets a lot of up-votes just for pointing out what's in the documentation...including [myself](http://stackoverflow.com/a/3909907/355230). Same for questions that could have been answered by reading it... – martineau Jun 17 '12 at 22:30
  • @martineau, I agree in general; but to be fair to Ben Alpert, in this particular case, the information _is_ rather buried. Also, although the docs do mention `Random`, they don't say what parameters its constructor takes, and that information is directly relevant to the question. I'll admit to being a little proud of myself for remembering to [Use The Source, Luke](http://www.codinghorror.com/blog/2012/04/learn-to-read-the-source-luke.html). – senderle Jun 17 '12 at 23:25
  • @martineau: For comparison, my most upvoted answer: http://stackoverflow.com/questions/1020568/how-does-one-convert-a-string-to-lowercase-in-ruby/1020571#1020571. :\ I like checking the PyPy source for the library source but usually I shy away from CPython's. – Sophie Alpert Jun 18 '12 at 18:16
  • @senderle: Well, yeah, in this case it was "way" down in the 4th paragraph, and the link to the source is right up top. I suppose many don't bother checking the documentation because they assume it sucks which is often the case with software. While not perfect, Python's is pretty decent, and it's too bad more people don't at least take a glance at it -- beyond even the first 3 paragraphs -- before asking questions. – martineau Jun 18 '12 at 18:56
  • @Ben Alpert: Indeed, the pypy sources can be useful for this and other purposes -- I've used it myself. In this case however, the standard library module is apparently written in Python, too, as evidenced by the link to its code in the online documentation for the `random` module. – martineau Jun 18 '12 at 19:03
  • @martineau: I read "Class Random can also be subclassed if you want to use a different basic generator of your own devising" as well as the docs for seed, getstate, setstate, and jumpahead. Sorry for missing the one sentence that mentioned that Random can be instantiated manually. – Sophie Alpert Jun 18 '12 at 19:27
  • @Ben Alpert: Point taken -- put that way does make it sound like an obscure point. I suspected you *must* have read beyond the 3rd paragraph in the documentation since, obviously, you were aware of a number of the less frequently-used functions in the module mentioned further down. Sorry for any offense felt. – martineau Jun 18 '12 at 20:18