more_itertools
实现了 random_combinations
itertools 的算法,如果给定一个排序好的输入,它会返回 r
个排序好的随机数。
import more_itertools as mit
mit.random_combination(range(1000, 10000), r=100)
这与random.sample
不同,后者返回的结果是未排序的。
详情
看一下这个配方,我们就能明白为什么要按照这个顺序进行。
来自itertools recipes:
def random_combination(iterable, r):
"""Return a random *r* length subsequence of the elements in *iterable*.
>>> random_combination(range(5), 3) # doctest:+SKIP
(2, 3, 4)
This equivalent to taking a random selection from
``itertools.combinations(iterable, r)``.
"""
pool = tuple(iterable)
n = len(pool)
indices = sorted(sample(range(n), r))
return tuple(pool[i] for i in indices)
range()
是天生排序的,成为随机选择元素的pool
。虽然索引是随机选择的,但它们后来被排序了。由于pool
和indices
都是排序的,结果也是排序的。
总之,这与@Volatility的答案相同,只是排序是由系统自动处理的。
Cavaet: random_combinations
要求可迭代对象的长度超过r
的值,否则会引发错误。