Reproducibility of random numbers (Python 2/random)

395 views Asked by At

In Python 2 documentation of the random.seed() function I found a warning:

If a hashable object is given, deterministic results are only assured when PYTHONHASHSEED is disabled.

From https://docs.python.org/2/using/cmdline.html#envvar-PYTHONHASHSEED I infer that the -R switch of the interpreter may have similar effect as PYTHONHASHSEED.

I have verified empirically, that random numbers seeded with small integers seems to be reproducible. So do hashes of small integers.

However, int is hashable. Is it stated explicitly in any trusted source, that it is safe to use it as a seed for a reproducible sequence of random numbers?

In contrast to Reproducibility of python pseudo-random numbers across systems and versions?, reproducibility within same system and interpreter is enough.

2

There are 2 answers

0
abukaj On BEST ANSWER

The documentation confirms its safety in Python 2.6:

If x is not None or an int or long, hash(x) is used instead. If x is an int or long, x is used directly.

(from https://docs.python.org/2.6/library/random.html#random.seed)

[EDIT]

The documentation for 2.7 has been updated to:

If a is not None or an int or a long, then hash(a) is used instead. Note that the hash values for some types are nondeterministic when PYTHONHASHSEED is enabled.

3
Tadhg McDonald-Jensen On

Not a complete answer but the source code for random_seed (in C) would be relevent:

if (PyInt_Check(arg) || PyLong_Check(arg))
    n = PyNumber_Absolute(arg);
else {
    long hash = PyObject_Hash(arg);
    if (hash == -1)
        goto Done;
    n = PyLong_FromUnsignedLong((unsigned long)hash);
}

this would suggest that anything other then a long (int) directly uses the hash value as the seed, so as long as:

  1. hash(int) gives consistent results and
  2. You are using this implementation of seed (may not be the same for Jython etc.)

Then I'd expect seed(int) to yield consistent results.

That said I can't speak for either of those conditions staying constant so this doesn't really give a definitive answer unless someone else can verify them.