我们可以使用
random.sample
生成随机组合,并使用一个集合来确保我们不会生成任何重复的组合。以下是一个简单的演示。
from random import seed, sample
seed(42)
def random_combinations(seq, size, num):
combos = set()
while len(combos) < num:
item = sample(seq, size)
combos.add(tuple(item))
return list(combos)
data = [
(0, 1), (2, 3), (4, 5), (6, 7), (8, 9),
(10, 11), (12, 13), (14, 15), (16, 17), (18, 19),
]
combos = random_combinations(data, 3, 20)
for i, item in enumerate(combos, 1):
print('{:>2}: {}'.format(i, item))
输出
1: ((2, 3), (12, 13), (8, 9))
2: ((6, 7), (18, 19), (4, 5))
3: ((2, 3), (16, 17), (18, 19))
4: ((0, 1), (4, 5), (12, 13))
5: ((14, 15), (10, 11), (4, 5))
6: ((2, 3), (0, 1), (8, 9))
7: ((6, 7), (16, 17), (0, 1))
8: ((12, 13), (2, 3), (8, 9))
9: ((6, 7), (14, 15), (8, 9))
10: ((10, 11), (18, 19), (8, 9))
11: ((0, 1), (14, 15), (2, 3))
12: ((18, 19), (10, 11), (6, 7))
13: ((18, 19), (12, 13), (0, 1))
14: ((10, 11), (8, 9), (4, 5))
15: ((8, 9), (2, 3), (6, 7))
16: ((2, 3), (0, 1), (6, 7))
17: ((16, 17), (6, 7), (12, 13))
18: ((2, 3), (12, 13), (18, 19))
19: ((0, 1), (2, 3), (6, 7))
20: ((6, 7), (10, 11), (2, 3))
正如 tobias_k 在评论中提到的那样,此代码仅适用于 num 不太接近总组合数的情况。如果您想要的是总组合数的小于50%,那么它应该没问题,但超过这个范围后,其重新生成已经生成的组合的概率将很高,这将导致循环时间长。
请注意,此代码认为 ((2, 3), (12, 13), (8, 9)) 与包含这3对不同顺序的元组是不同的,例如 ((2, 3), (8, 9), (12, 13))。
如果您不希望出现这种情况,我们可以将项目变成集合。为此,我们需要使用 frozenset,因为普通集合是可变集合,因此是无法哈希的,因此不能成为集合项。
from random import seed, sample
seed(42)
def random_combinations(seq, size, num):
combos = set()
while len(combos) < num:
item = sample(seq, size)
combos.add(frozenset(item))
return [tuple(u) for u in combos]
data = [
(0, 1), (2, 3), (4, 5), (6, 7), (8, 9),
(10, 11), (12, 13), (14, 15), (16, 17), (18, 19),
]
combos = random_combinations(data, 3, 20)
for i, item in enumerate(combos, 1):
print('{:>2}: {}'.format(i, item))
输出
1: ((0, 1), (2, 3), (6, 7))
2: ((0, 1), (2, 3), (8, 9))
3: ((16, 17), (6, 7), (0, 1))
4: ((12, 13), (2, 3), (18, 19))
5: ((12, 13), (2, 3), (8, 9))
6: ((12, 13), (18, 19), (0, 1))
7: ((8, 9), (4, 5), (10, 11))
8: ((16, 17), (2, 3), (18, 19))
9: ((8, 9), (6, 7), (14, 15))
10: ((0, 1), (4, 5), (12, 13))
11: ((8, 9), (10, 11), (18, 19))
12: ((10, 11), (6, 7), (2, 3))
13: ((0, 1), (14, 15), (2, 3))
14: ((10, 11), (18, 19), (6, 7))
15: ((8, 9), (2, 3), (6, 7))
16: ((4, 5), (6, 7), (18, 19))
17: ((8, 9), (4, 5), (2, 3))
18: ((16, 17), (4, 5), (6, 7))
19: ((16, 17), (6, 7), (12, 13))
20: ((4, 5), (10, 11), (14, 15))
itertools.combinations
返回一个迭代器,它不会一次性创建所有的组合。因此,只需循环遍历组合,并在获得足够的组合时退出循环。它们将按顺序排列,而不是随机的。这有关系吗? - PM 2Ringitertools.combinations('ABCD', 2)[:(len('ABCD')*percent)]
- dsgdfg