保证lis的洗牌

2024-04-20 04:13:57 发布

您现在位置:Python中文网/ 问答频道 /正文

给定一个列表/有序集合,有没有一种方法可以产生一个有保证的对其成员的洗牌/重新排序(意味着没有一个元素像以前一样处于相同的位置),而不需要尝试和错误?我在这里使用python,但这显然适用于任何具有这种结构的语言。你知道吗

例如,如果我有一个列表l = [1, 2, 3, 4, 5]并随机地将其洗牌:

import random                                                                                                                                                                                                                                                                                                                             

for _ in range(5): 
    random.shuffle([1,2,3,4,5]); 
    print(l) 
[1, 2, 3, 5, 4] # 1,2,3
[2, 4, 3, 1, 5] # 3, 5
[2, 1, 4, 5, 3] # OK!
[2, 5, 3, 1, 4] # 3
[5, 3, 4, 2, 1] # OK!

您可以看到,只有第3和第4个输出all元素确实位于列表中的不同位置,而在其他情况下,我编写的列表元素仍然位于相同的位置。你知道吗

更为体贴的方法,如在每个位置省略冒犯的元素:

l=[1,2,3,4,5]
shuffled = []
for i in l:
    sample_from = [x for x in l if x not in shuffled + [i]]
    try:
        shuffled.append(random.sample(sample_from, 1)[0])
    except:
        print("Attempted to sample from", sample_from)
        break
    print("Shuffled portion:", shuffled)

可能会导致错误而没有可行的解决方案,例如:

Shuffled portion: [2]
Shuffled portion: [2, 4]
Shuffled portion: [2, 4, 1]
Shuffled portion: [2, 4, 1, 3]
Attempted to sample from []

其中5恰好被留到了结尾,没有其他位置可以替代原来的位置。我想当我到达这个位置时,我可以用无序列表中的任何元素交换剩余的5。你知道吗

然而,有没有其他更简单,更漂亮和算法的方法来实现这一点,没有这样的手动黑客? 谢谢!你知道吗


Tags: sample方法infrom元素列表for错误
1条回答
网友
1楼 · 发布于 2024-04-20 04:13:57

要生成混乱,可以使用Fisher-Yates洗牌算法,在选择要交换的索引时,只需将当前索引排除在考虑范围之外(即,不允许将元素本身交换)。你知道吗

相关问题 更多 >