打乱一小组项目

2 投票
3 回答
1407 浏览
提问于 2025-04-20 06:37

如果我用Python的random.shuffle来打乱一个小列表,我发现有时候结果并没有被打乱。

import random

for i in range(10):
    ori = [1, 2, 3]
    per = ori[:]
    random.shuffle(per)
    print i, per, (per == ori) or ""

这里有一个示例输出:

0 [1, 3, 2] 
1 [1, 2, 3] True
2 [3, 1, 2] 
3 [2, 3, 1] 
4 [1, 2, 3] True
5 [2, 3, 1] 
6 [3, 2, 1] 
7 [2, 1, 3] 
8 [2, 1, 3] 
9 [2, 1, 3] 

我查看了算法的细节后,明白了这可能是必然的情况[1][2]。但是我真的想要一个小的无序列表(比如3到6个项目),希望能通过编程实现。

你觉得有什么好的方法可以做到这一点呢?

3 个回答

-1

因为这个数组很短,所以可以手动快速打乱一下:

import random

for i in range(len(ori) - 1):
    j = random.randint(i + 1, len(ori) - 1)
    ori[i], ori[j] = ori[j], ori[i]

这样你就能确保不会得到原来的数组。这种方法的效率是O(n),所以只适合用在小数组上。

4

如果你必须不按照原来的顺序来排列,那你可以简单地重新洗牌,直到per != ori为止。

1

一种方法是生成列表的所有排列组合,然后把第一个排列去掉。之后,你可以使用 random.choice 来随机选择其中的一个排列:

>>> from random import choice
>>> from itertools import permutations
>>> data = list(permutations([1, 2, 3], 3))[1:]
>>> for _ in range(10):
...     print choice(data)
...     
(3, 2, 1)
(3, 2, 1)
(2, 1, 3)
(1, 3, 2)
(1, 3, 2)
(1, 3, 2)
(3, 2, 1)
(2, 3, 1)
(2, 3, 1)
(2, 1, 3)

撰写回答