Перетасовка python с параметром, чтобы получить тот же результат

import random
x = [1, 2, 3, 4, 5, 6]
random.shuffle(x)
print x

Я знаю, как перетасовать список, но можно ли перетасовать его с таким параметром, чтобы перетасовка давала одинаковый результат каждый раз?

Что-то вроде;

random.shuffle(x,parameter)

и результат будет таким же для этого параметра. Параметр Say 4 и результат [4, 2, 1, 6, 3, 5] каждый раз.

Ответ 1

Как поясняется в документации:

Функции, предоставляемые этим модулем, являются фактически связанными методами скрытого экземпляра класса random.Random. Вы можете создавать собственные экземпляры Random для генерации генераторов, не имеющих общего состояния.

Таким образом, вы можете просто создать свой случай random.Random с его собственным семенем, который вообще не повлияет на глобальные функции:

>>> import random
>>> x = [1, 2, 3, 4, 5, 6]
>>> random.Random(4).shuffle(x)
>>> x
[4, 6, 5, 1, 3, 2]
>>> x = [1, 2, 3, 4, 5, 6]
>>> random.Random(4).shuffle(x)
>>> x
[4, 6, 5, 1, 3, 2]

(Вы можете также держать вокруг Random экземпляра и re- seed его вместо того, чтобы создавать новые снова и снова,. Не слишком большой разницы)

Ответ 2

Вы можете установить seed (который принимает parameter) вашего случайного генератора, который определит ваш метод перетасовки

import random
x = [1, 2, 3, 4, 5, 6]
random.seed(4)
random.shuffle(x)
print x

и результат должен быть всегда

[2, 3, 6, 4, 5, 1]

Чтобы "повторить ранжирование" остальной части кода, вы можете просто перезагрузить генератор случайных чисел с системным временем, запустив

random.seed()

после вашей "детерминированной" части кода

Ответ 3

Перетасовка с фиксированным значением для random НЕ работает! Пример:

from random import shuffle
v = sum([[k] * 100 for k in range(10)], [])
print v[:40]
shuffle(v, random = lambda: 0.7)
print v[:40]

Выдает вывод:

[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 8, 0, 0, 9, 0, 0, 0, 9, 0, 0, 8, 0, 0, 7, 0, 0, 0, 9, 0, 0, 7, 0, 0, 8, 0, 0, 0, 7, 0, 0, 7, 0, 0, 8, 0, 0, 0, 9]

Он похож на другие семена - не очень случайный (на первый взгляд все равно... трудно доказать). Это связано с тем, что random не является семенем - он многократно используется многократно. Демонстрация:

def rand_tracker():
    rand_tracker.count += 1
    return random()
rand_tracker.count = 0
shuffle(v, random = rand_tracker)
print 'Random function was called %d times for length %d list.' % (rand_tracker.count, len(v))

Что показывает:

Random function was called 999 times for length 1000 list.

Вместо этого вам следует предложить @abarnert:

from random import Random
Random(4).shuffle(x)

В этом случае фиксированное значение отлично.

TL;DR: используйте ответ @abarnert, не используйте функцию фиксированного значения для random!

Ответ 4

Из python ссылка:

Необязательный аргумент random - это функция 0-аргумента, возвращающая случайный float в [0.0, 1.0]; по умолчанию это функция random()

Вы можете использовать функцию лямбда, которая всегда возвращает то же значение, что и семя для shuffle:

In [7]: l = [1,2,3,4]
In [8]: random.shuffle(l, lambda: .5)

In [9]: l
Out[9]: [1, 4, 2, 3]

In [10]: l = [1,2,3,4]

In [11]: random.shuffle(l, lambda: .5)

In [12]: l
Out[12]: [1, 4, 2, 3]  # same order as Out[9]