25

I am trying to reproduce a random sequence from python's random.random() on a different system with a different python3 version installed.

This should be easy as the documentation says:

Most of the random module’s algorithms and seeding functions are subject to change across Python versions, but two aspects are guaranteed not to change:

  • If a new seeding method is added, then a backward compatible seeder will be offered.
  • The generator’s random() method will continue to produce the same sequence when the compatible seeder is given the same seed.

So I expect the following code to print always the same 10 numbers, no matter the specific python3 version:

import sys
print(sys.version)

from random import seed, random

seed(str(1))
for i in range(10):
    print(random())

However, testing it on two different machines:

3.2.3 (default, May  3 2012, 15:51:42) 
[GCC 4.6.3]
0.4782479962566343
0.044242767098090496
0.11703586901195051
0.8566892547933538
0.2926790185279551
0.0067328440779825804
0.0013279506360178717
0.22167546902173108
0.9864945747444945
0.5157002525757287

and

3.1.2 (release31-maint, Dec  9 2011, 20:59:40)  
[GCC 4.4.5]
0.0698436845523
0.27772471476
0.833036057868
0.35569897036
0.36366158783
0.722487971761
0.963133581734
0.263723867191
0.451002768569
0.0998765577881

Give different results.

Why is this? And is there any way to make this to work (i.e. get the same random sequence twice?)

p-a-o-l-o
  • 9,807
  • 2
  • 22
  • 35
Peter Smit
  • 27,696
  • 33
  • 111
  • 170
  • 1
    for what it's worth, running your code snippet in 2.7 produces a completely different set of numbers than either of the two you posted. – Jeff Tratner Aug 13 '12 at 07:20
  • 3
    It states *a backward compatible seeder will be offered* not that the existing method will be backward compatible. – borrible Aug 13 '12 at 07:25

2 Answers2

21

I was looking through What's New in Python 3.2 (because of this question), and I found:

The random.seed() function and method now salt string seeds with an sha512 hash function. To access the previous version of seed in order to reproduce Python 3.1 sequences, set the version argument to 1, random.seed(s, version=1).

It appears to be a breaking change (from 3.1 to 3.2) with a backwards compatibility option.

(As borrible pointed out, because a compatible seeder is offered the documentation contract has not been violated.)

  • 1
    Thanks, this must be the problem. I must say that it is not very convenient that the version argument was not present yet in 3.1 :( – Peter Smit Aug 13 '12 at 07:29
  • 1
    That applies when you use string seeds. Unlike the OP, I'm seeding my random number generator with ints, and seeing different results. Incidentally, the getstate() method returns the same internal state, so it's not the seeding bit that changed, it's actual random nuumber generation. – Marius Gedminas Feb 08 '13 at 07:36
  • 5
    Oh, actually I see random.random() produce the same sequence -- it's random.shuffle() and random.randrange() that produce different results on Python 3.1 and 3.2, even when given the same seed. :-( – Marius Gedminas Feb 08 '13 at 07:38
6

The docs for seed say that they use the hash function to convert strings to valid input seeds. When I tested various versions of Python2.X (don't have 3 installed at the moment), some versions gave different values for hash(str(1)) Note that the docs for seed say that, regardless of version, they use the hash value for the string. You might want to pass an int instead (in addition to @pst 's point about using the backwards-compatible version of seed).

Snippet from the random module docs for 3.2:

If x is an int, it is used directly.

With version 2 (the default), a str, bytes, or bytearray object gets converted to an int and all of its bits are used. With version 1, the hash() of x is used instead.

(x here is the initializer for seed)

Jeff Tratner
  • 16,270
  • 4
  • 47
  • 67