curious curious - 3 months ago 15
Python Question

Keyed Random Shuffles in Python

I have a list

a=[num1,num2,...,numn]
. I am shuffling it with
random.shuffle(a)
. However what I want as a functionality is the shuffle algorithm to take as input a key, and the owner of the key to deterministically produce the same shuffles?

I want an algorithm that takes as input the key, the sequence of elements to be shuffled and it outputs a random permutation thereof, depending on the key. If you apply the shuffle again with input the same key on the same sequence of data you are getting the same result. Otherwise random shuffle. The same key on the same data allows to "un-shuffle"

Is that possible?

Answer

In pseudo-random terminology, that key is called a seed, and you can set the random seed on a new random.Random() instance:

def keyed_shuffle(x, seed=None):
    random_obj = random.Random(seed)
    random_obj.shuffle(x)

You could use random.seed() and random.shuffle() directly too, but using your own random.Random() instance avoids setting the seed on the singleton random.Random() instance that the random module uses, thus not affecting other uses of that module.

The seed can either be an integer (used directly) or any hashable object.

Demo:

>>> a = [10, 50, 42, 193, 21, 88]
>>> keyed_shuffle(a)       # no seed
>>> a
[42, 10, 88, 21, 50, 193]
>>> a = [10, 50, 42, 193, 21, 88]
>>> keyed_shuffle(a)       # again no seed, different random result
>>> a
[88, 50, 193, 10, 42, 21]
>>> b = [10, 50, 42, 193, 21, 88]
>>> keyed_shuffle(b, 42)   # specific seed
>>> b
[193, 50, 42, 21, 10, 88]
>>> b = [10, 50, 42, 193, 21, 88]
>>> keyed_shuffle(b, 42)   # same seed used, same output
>>> b
[193, 50, 42, 21, 10, 88]
>>> c = [10, 50, 42, 193, 21, 88]
>>> keyed_shuffle(b, 81)   # different seed, different random order
>>> c
[10, 50, 88, 42, 193, 21]
Comments