Python 合并itertools.product的结果?
我正在尝试使用Python 合并itertools.product的结果?,python,itertools,Python,Itertools,我正在尝试使用itertools.product从0-9999创建一个数字列表。我可以通过执行以下操作从0000-9999创建列表: numbers = ['0','1','2','3','4','5','6','7','8','9'] itertools.product(numbers,numbers,numbers,numbers) 虽然我想要像0001这样的条目,但我也想要得到001、01和1 包含这些内容的最有效方式是什么?我是否应该调用itertools.product(数字、数字、
itertools.product
从0-9999
创建一个数字列表。我可以通过执行以下操作从0000-9999
创建列表:
numbers = ['0','1','2','3','4','5','6','7','8','9']
itertools.product(numbers,numbers,numbers,numbers)
虽然我想要像0001
这样的条目,但我也想要得到001
、01
和1
包含这些内容的最有效方式是什么?我是否应该调用itertools.product(数字、数字、数字)
和itertools.product(数字、数字)
,然后以某种方式将它们与原始版本结合起来,还是有更干净的方法
如果我再打两个电话并合并,有人能告诉我怎么做吗?我试图使用.append()
,但它引发以下错误:
'itertools.product' object has no attribute 'append'
感谢您的帮助。您可以使用嵌套的listcomp或genexp(此处缩小尺寸以便于显示):
numbers = ['0','1','2','3','4','5','6','7','8','9']
list(''.join(subl) for subl in itertools.chain.from_iterable(itertools.product(numbers, repeat=i) for i in range(1,5)))
您可以使用嵌套的listcomp或genexp(出于显示目的,此处减小了大小):
现有答案的性能改进:
from itertools import chain, product
list(map(''.join, chain.from_iterable(product(numbers, repeat=i) for i in range(1, 5))))
# Or on Python 3.5+ with additional unpacking generalizations:
[*map(''.join, chain.from_iterable(product(numbers, repeat=i) for i in range(1, 5)))]
如果您只是在迭代结果,则省略list()
/[*…]
包装
CPython参考解释器的性能显著提高(在本例中不是很多,但对于更大的产品来说是非常显著的),如下所示(此处的实现细节):
product
在请求下一个结果时,如果不存在引用,则具有(包括不需要设置其中的大多数值)。这种优化不适用于listcomps和GeneXPR(循环结构使对结果的元组的引用保持活动状态的时间足够长,以便在确定是否可以为下一个结果重用元组时存在引用),但是映射(''.join
避免了这种情况(它只保存对元组的引用
足够长的时间来调用映射器函数,在生成映射器结果之前丢弃它)
ipython
microbenchmarks(在这种情况下,在Linux x64 3.6安装上)可以证明:
如前所述,这里的收益仅以百分比计算(运行时减少约27%);6.7μs在总体上是微不足道的。但是如果要覆盖的
范围越来越大,和/或到产品的集合越来越大,它就更重要了;对于数字='0123456789'
和范围(1,8)
,从2.54秒减少到1.67秒;逐渐地,节省的时间大约是三分之一,当总成本以秒计时,将该成本减少三分之一是有意义的。现有答案的性能改进:
from itertools import chain, product
list(map(''.join, chain.from_iterable(product(numbers, repeat=i) for i in range(1, 5))))
# Or on Python 3.5+ with additional unpacking generalizations:
[*map(''.join, chain.from_iterable(product(numbers, repeat=i) for i in range(1, 5)))]
如果您只是在迭代结果,则省略list()
/[*…]
包装
CPython参考解释器的性能显著提高(在本例中不是很多,但对于更大的产品来说是非常显著的),如下所示(此处的实现细节):
它将绝大多数工作推送到C层,避免了字节码解释器循环开销
product
在请求下一个结果时,如果不存在引用,则具有(包括不需要设置其中的大多数值)。此优化不适用于listcomps和GeneXPR(循环结构使对结果的元组的引用保持活动状态,直到在确定是否可以为下一个结果重用元组时引用存在为止),但是映射('''.join
避免了这种情况)(它只保存对元组的引用
足够长的时间来调用映射器函数,在生成映射器结果之前丢弃它)
即使在这种情况下,从百分比上看,加速效果也是显著的,通过ipython
microbenchmarks(在这种情况下,在Linux x64 3.6安装上)可以证明:
如前所述,这里的收益仅以百分比计算(运行时减少约27%);6.7μs在总体上是微不足道的。但是如果要覆盖的范围越来越大,和/或到产品的集合越来越大,它就更重要了;对于数字='0123456789'
和范围(1,8)
,减少时间从2.54秒减少到1.67秒;逐渐地,节省的时间大约是三分之一,当总成本以秒计算时,将该成本减少三分之一是有意义的
>>> %timeit -r5 [''.join(p) for n in range(1, 5) for p in product(nums, repeat=n)]
24.9 μs ± 95.2 ns per loop (mean ± std. dev. of 5 runs, 10000 loops each)
>>> %timeit -r5 list(map(''.join, chain.from_iterable(product(numbers, repeat=i) for i in range(1, 5))))
18.2 μs ± 41.2 ns per loop (mean ± std. dev. of 5 runs, 100000 loops each)