限制python中组合/排列的数量

Posted

技术标签:

【中文标题】限制python中组合/排列的数量【英文标题】:Limiting the number of combinations /permutations in python 【发布时间】:2014-05-18 13:33:09 【问题描述】:

我打算使用 itertools 生成一些组合,当我意识到随着元素数量的增加所花费的时间将成倍增加。我可以限制或指示要生成的最大排列数,以便在达到该限制后 itertools 将停止。

我的意思是:

目前我有

#big_list is a list of lists
permutation_list = list(itertools.product(*big_list))

目前这个排列列表有超过 600 万个排列。我很确定如果我再添加一个列表,这个数字将达到十亿大关。

我真正需要的是大量的排列(比如说 5000)。有没有办法限制生成的 permutation_list 的大小?

【问题讨论】:

你真的需要这份清单吗?迭代器占用的内存非常少,它的速度与(或超过)列表一样快。 【参考方案1】:

你需要使用itertools.islice,像这样

itertools.islice(itertools.product(*big_list), 5000)

它不会在内存中创建整个列表,但它会返回一个迭代器,该迭代器会延迟使用实际的可迭代对象。您可以将其转换为这样的列表

list(itertools.islice(itertools.product(*big_list), 5000))

【讨论】:

这是正确的解决方案,因为它还可以让您轻松设置启动和停止。【参考方案2】:

itertools.islice 有很多好处,例如能够设置startstep。下面的解决方案不是那么灵活,只有当 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 与第一个解决方案一样。

【讨论】:

@frostnational。很好的解决方案,效果很好。不幸的是,我只能将一个答案标记为已接受。但这同样有效。谢谢 或者您可以完全跳过permutation_generator 并使用列表理解。或者更简单,[x for _, x in zip(xrange(5000), iterator)]【参考方案3】:

您可以尝试这种方法来获得特定的排列数 排列产生的结果数是 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

【讨论】:

以上是关于限制python中组合/排列的数量的主要内容,如果未能解决你的问题,请参考以下文章

python中的排列组合

Python 排列组合

HDU 1521 排列组合 搜索

HDU 1521 排列组合

Python3 - 排列组合的迭代

当数组的数量和每个数组的长度未知时生成字符组合的所有排列