Подтвердить что ты не робот

Почему семена случайного генератора не стабильны между версиями Python?

Я пытаюсь воспроизвести случайную последовательность из python random.random() в другой системе с установленной версией python3.

Это должно быть легко, поскольку документация :

Большинство алгоритмов случайных модулей и функции посева могут быть изменены в версиях Python, но два аспекта: гарантированно не изменится:

  • Если новый метод посева добавлен, то обратная совместимая сеялка будет предложено.
  • Метод генераторов random() будет продолжать производят такую ​​же последовательность, когда совместимой сеялке дают одинаковые семян.

Поэтому я ожидаю, что следующий код будет печатать всегда те же 10 чисел, независимо от конкретной версии python3:

import sys
print(sys.version)

from random import seed, random

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

Однако, тестируя его на двух разных машинах:

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

и

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

Дайте разные результаты.

Почему это? И есть ли способ заставить это работать (т.е. Получить одну и ту же случайную последовательность в два раза?)

4b9b3361

Ответ 1

Я просматривал Что нового в Python 3.2 (из-за этого вопроса), и я обнаружил:

Функция и метод random.seed() теперь сольют семена семян с помощью хэш-функции sha512. Чтобы получить доступ к предыдущей версии семпла, чтобы воспроизвести последовательности Python 3.1, установите аргумент версии 1, random.seed(s, version = 1).

Кажется, что это изменение прерывания (от 3.1 до 3.2) с возможностью обратной совместимости.

(Как указано в borrible, поскольку предлагается совместимая сеялка, контракт на документацию не был нарушен.)

Ответ 2

Документы для seed говорят, что они используют хеш-функцию для преобразования строк в действительные семплы ввода. Когда я тестировал различные версии Python2.X(на данный момент не установлено 3), некоторые версии дали разные значения для hash(str(1)) Обратите внимание, что документы для семени говорят, что независимо от версии они используют значение hash для строки. Возможно, вам захочется передать int (в дополнение к точке @pst об использовании обратной семантической версии семян).

Фрагмент из random docs для 3.2:

Если x является int, он используется напрямую.

С версией 2 (по умолчанию) объект str, bytes или bytearray получает преобразуется в int и все его биты используются. С версией 1 Вместо этого используется хеш() x.

(x здесь инициализатор для семян)