Python笛卡尔发电机在功率列表上

时间:2014-03-25 22:45:07

标签: python iterator generator itertools cartesian-product

如何创建一个由itertools.product()生成的Python生成器,但迭代重复值列表?它的行为就像这个嵌套的for循环:

theSet = 'ABC'
thePowers = range(4)

for i in thePowers:
    for j in itertools.product(theSet, repeat=i):
        print j

但是我希望它是一个生成器,这样会产生相同的输出:

for p in myGenerator:
    print p

3 个答案:

答案 0 :(得分:1)

from itertools import product

def my_generator(values, *start_stop_step):
    for i in range(*start_stop_step):
        for j in product(values, repeat=i):
            yield ''.join(j)

for p in my_generator("ABC", 4):
    print(p)

给出了

   # <= that was a null string ie ''
A
B
C
AA
AB
AC
BA
BB
...
CCA
CCB
CCC

答案 1 :(得分:1)

你可以为它定义一个生成器函数..

>>> from itertools import product
>>> def my_gen(letters, powers):
...     for power in powers:
...         for cartesian in product(letters, repeat=power):
...             yield cartesian
...         
...     
... 
>>>

并像这样使用它:

>>> for p in my_gen("ABC", range(4)):
...    print p
()
('A',)
('B',)
('C',)
('A', 'A')
('A', 'B')
('A', 'C')
('B', 'A')
('B', 'B')
('B', 'C')
('C', 'A')
('C', 'B')
('C', 'C')
('A', 'A', 'A')
('A', 'A', 'B')
('A', 'A', 'C')
('A', 'B', 'A')
('A', 'B', 'B')
('A', 'B', 'C')
('A', 'C', 'A')
('A', 'C', 'B')
('A', 'C', 'C')
('B', 'A', 'A')
('B', 'A', 'B')
('B', 'A', 'C')
('B', 'B', 'A')
('B', 'B', 'B')
('B', 'B', 'C')
('B', 'C', 'A')
('B', 'C', 'B')
('B', 'C', 'C')
('C', 'A', 'A')
('C', 'A', 'B')
('C', 'A', 'C')
('C', 'B', 'A')
('C', 'B', 'B')
('C', 'B', 'C')
('C', 'C', 'A')
('C', 'C', 'B')
('C', 'C', 'C')

您也可以使用生成器表达式!

>>> products = list(product("ABC", repeat=i) for i in range(4))
>>> result = list(x for lst in products for x in lst)
>>> result
[(), ('A',), ('B',), ('C',), ('A', 'A'), ('A', 'B'), ('A', 'C'), ('B', 'A'), ('B
', 'B'), ('B', 'C'), ('C', 'A'), ('C', 'B'), ('C', 'C'), ('A', 'A', 'A'), ('A',
'A', 'B'), ('A', 'A', 'C'), ('A', 'B', 'A'), ('A', 'B', 'B'), ('A', 'B', 'C'), (
'A', 'C', 'A'), ('A', 'C', 'B'), ('A', 'C', 'C'), ('B', 'A', 'A'), ('B', 'A', 'B
'), ('B', 'A', 'C'), ('B', 'B', 'A'), ('B', 'B', 'B'), ('B', 'B', 'C'), ('B', 'C
', 'A'), ('B', 'C', 'B'), ('B', 'C', 'C'), ('C', 'A', 'A'), ('C', 'A', 'B'), ('C
', 'A', 'C'), ('C', 'B', 'A'), ('C', 'B', 'B'), ('C', 'B', 'C'), ('C', 'C', 'A')
, ('C', 'C', 'B'), ('C', 'C', 'C')]

答案 2 :(得分:1)

您可以使用'yield'关键字轻松完成此操作。这是我发现的非常清楚的博客:https://www.jeffknupp.com/blog/2013/04/07/improve-your-python-yield-and-generators-explained/

import itertools

def iterate():
    theSet = 'ABC'
    thePowers = range(4)

    output = []
    for i in thePowers:
        for j in itertools.product(theSet, repeat=i):
            output.append(j)
    return output

def generate():
    theSet = 'ABC'
    thePowers = range(4)

    for i in thePowers:
        for j in itertools.product(theSet, repeat=i):
            yield j

a = iterate()
b = [output for output in generate()]
print(a == b) # True

最后一个声明向我们保证输出是相同的。我想你会想做一些比生成值更复杂的事情。