A good way to shuffle and then unshuffle a python list

这一生的挚爱 提交于 2019-12-12 06:56:49

问题


So lets say i have a list of tuples

l=[(1,2),(3,4),(5,6),(7,8),(9,10)]

I want to shuffle the values after a specific rule, so that after i shuffle the list i can unshuffle it back using the same method.

One example would be that i shift the entire list to the right with 1 position and then i can shift the shuffled list with one position to the left so i can get the original list.

But this seems kinda simple so i was wondering if they're more creative methods of doing this

Edit: The idea would be that if i send someone the shuffled list, he could unshuffle it without knowing the original list,only knowing the method used for shuffle


回答1:


You could choose some algorithm to determine a seed that can be derived from the list itself and does not depend on its order.

For the example data structure, the seed could for instance be the sum of all values. Then with that seed you would generate a random (but deterministic) permutation of the numbers from 0 to n-1. That permutation can then be used as a basis for the shuffle and unshuffle functions:

import random

def getperm(l):
    seed = sum(sum(a) for a in l)
    random.seed(seed)
    perm = list(range(len(l)))
    random.shuffle(perm)
    random.seed() # optional, in order to not impact other code based on random
    return perm

def shuffle(l):
    perm = getperm(l)
    l[:] = [l[j] for j in perm]

def unshuffle(l):
    perm = getperm(l)
    res = [None] * len(l)
    for i, j in enumerate(perm):
        res[j] = l[i]
    l[:] = res

Example call:

l=[(1,2),(3,4),(5,6),(7,8),(9,10)]   
print(l)    
shuffle(l)
print(l) # shuffled
unshuffle(l)
print(l)  # the original



回答2:


I suppose you could apply any shuffle you like, so long as you can seed your random source.

Take a list with the numbers 0 to n, and shuffle it. Use the order of this list to shuffle your list of tuples, e.g. if the first element of your list after shuffling is 5, then the first element in your shuffled list of tuples is l[5]. You can then do the inverse: the first element in your shuffled list of tuples is the 5th element in your list of unshuffled tuples.

If you seed your random source, you can recreate your list of shuffled numbers just by running the same shuffle on the same list of 0 to n. You can then use this to unshuffled your list of shuffled tuples, as before.

Edit: trincot's answer implements this idea, but with working sample code.




回答3:


Are you looking for deque?

from collections import deque

d = deque([(1,2),(3,4),(5,6),(7,8),(9,10)])

d.rotate(1)
deque([(9, 10), (1, 2), (3, 4), (5, 6), (7, 8)])

d.rotate(-1)
deque([(1, 2), (3, 4), (5, 6), (7, 8), (9, 10)])


来源:https://stackoverflow.com/questions/54724334/a-good-way-to-shuffle-and-then-unshuffle-a-python-list

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!