比方说,我有两个迭代,一个有限和一个无限:
import itertools
teams = ['A', 'B', 'C']
steps = itertools.count(0, 100)
[我想知道是否可以避免嵌套的for循环,并使用itertools
模块中的无限迭代器之一,例如itertools
或cycle
来获取这些可迭代对象的笛卡尔积。
循环应该是无限的,因为repeat
的停止值是预先未知的。
预期输出:
steps
具有嵌套循环的工作代码:
$ python3 test.py
A 0
B 0
C 0
A 100
B 100
C 100
A 200
B 200
C 200
etc...
尝试from itertools import count, cycle, repeat
STEP = 100
LIMIT = 500
TEAMS = ['A', 'B', 'C']
def test01():
for step in count(0, STEP):
for team in TEAMS:
print(team, step)
if step >= LIMIT: # Limit for testing
break
test01()
itertools.product
正如文档所说,itertools.product
等于from itertools import product
for i, j in product(range(0, 501, 100), 'ABC'):
print(j, i)
。如您所见,product(A, B)
生成一个元组,这意味着它是一个生成器,并且不会在内存中创建列表以正常工作。
此函数大致等效于以下代码,不同之处在于实际实现不会在内存中建立中间结果:
((x,y) for x in A for y in B)
但是由于product
,您不能将def product(*args, **kwds):
# product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy
# product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111
pools = map(tuple, args) * kwds.get('repeat', 1)
result = [[]]
for pool in pools:
result = [x+[y] for x in result for y in pool]
for prod in result:
yield tuple(prod)
用于无限循环:
根据文档,itertools.product等效于 生成器表达式中嵌套的for循环。但, itertools.product(itertools.count(2010))不是。
itertools.product
itertools.product的输入必须是有限的有限序列 迭代器。
对于无限循环,可以使用known issue。
[tomjn的答案对于有限循环是最好的,因此,如果您不想使用>>> import itertools
>>> (year for year in itertools.count(2010))
<generator object <genexpr> at 0x026367D8>
>>> itertools.product(itertools.count(2010))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
MemoryError
(对于无限循环),则可以使用此答案:
this code