限制Python中的组合/排列数量
我本来打算用itertools生成一些组合,但我发现随着元素数量的增加,所需的时间会呈指数级增长。请问有没有办法限制或指明要生成的排列最大数量,这样itertools在达到这个限制后就会停止?
我想说的是:
目前我有
#big_list is a list of lists
permutation_list = list(itertools.product(*big_list))
现在这个排列列表有超过600万种排列。如果我再加一个列表,这个数字肯定会达到十亿。
我真正需要的是相对较少的排列(比如说5000个)。有没有办法限制生成的排列列表的大小?
3 个回答
0
你可以试试这个方法来获取特定数量的排列结果。排列的结果数量是用n!来表示的,其中n代表列表中元素的数量。比如说,如果你只想得到2个结果,你可以尝试下面的方法:
使用一个临时变量,并给它设定一个限制。
from itertools import permutations
m=['a','b','c','d']
per=permutations(m)
temp=1
for i in list(per):
if temp<=2: #2 is the limit set
print (i)
temp=temp+1
else:
break
1
itertools.islice
有很多好处,比如可以设置 start
和 step
。下面的解决方案灵活性不高,只适合在 start
为 0 和 step
为 1 的情况下使用。另一方面,它们不需要任何额外的导入。
你可以在 itertools.product
周围创建一个小的封装
it = itertools.product(*big_list)
pg = (next(it) for _ in range(5000)) # generator expression
(next(it) for _ in range(5000))
这个表达式会返回一个生成器,它最多只能产生 5000 个值。你可以通过使用 list
构造函数将其转换为 list
pl = list(pg)
或者通过用方括号包裹生成器表达式(而不是用圆括号)来实现
pl = [next(it) for _ in range(5000)] # list comprehension
另一种解决方案和第一种一样高效,具体如下
pg = (p for p, _ in zip(itertools.product(*big_list), range(5000))
这个方法在 Python 3+ 中有效,其中 zip
会返回一个迭代器,当最短的可迭代对象耗尽时就会停止。转换为 list
的方式和第一种解决方案一样。
10
你需要使用 itertools.islice
,像这样
itertools.islice(itertools.product(*big_list), 5000)
它不会把整个列表都放到内存里,而是返回一个迭代器,这个迭代器会懒惰地消耗实际的可迭代对象。你可以像这样把它转换成列表
list(itertools.islice(itertools.product(*big_list), 5000))