整理然后重新整理python列表的好方法

时间:2019-02-16 14:56:07

标签: python list shuffle

所以可以说我有一个元组列表

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

我想按照特定规则对值进行混排,以便在对列表进行混排后可以使用相同的方法将其重新混排。

一个例子是,我将整个列表向右移动1个位置,然后我可以将混洗后的列表向左移动一个位置,以便获得原始列表。

但这似乎很简单,所以我想知道他们是否是更具创造性的方法

编辑:我的想法是,如果我向某人发送经过改组的列表,他可以不了解原始列表而只知道用于改组的方法来对其进行改组

3 个答案:

答案 0 :(得分:2)

我想只要您可以为随机来源提供种子,您都可以应用任何喜欢的混洗。

从0到n的列表中选取一个,然后将其随机排列。使用此列表的顺序来随机排列元组列表,例如如果改组后列表的第一个元素是5,那么在改组后的元组列表中的第一个元素是l[5]。然后,您可以进行反操作:拖曳的元组列表中的第一个元素是未拖曳的元组列表中的第5个元素。

如果您为随机数源添加种子,则只需在0到n的相同列表上运行相同的随机播放,就可以重新创建随机数字的列表。然后,您可以像以前一样使用它来取消混洗的元组列表。

编辑:Trincot的答案实现了这个想法,但带有有效的示例代码。

答案 1 :(得分:0)

您要寻找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)])

答案 2 :(得分:0)

您可以选择某种算法来确定可以从列表本身派生的种子,而不取决于其顺序。

对于示例数据结构,种子可以是例如所有值的总和。然后,使用该种子,您将生成数字从0到n-1的随机(但确定性)排列。然后,该排列可以用作随机播放和取消随机播放功能的基础:

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

示例调用:

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