Search code examples
pythoniteratorreturnyield

How to flatten out the yield when yielding a generator?


I have this function g() my goal is to yield a result similar to product() but with constrained number of appearance for each group of characters. So in the code below instead of doing product(a, repeat=3) g() is supposed to yield all the combinations where characters from a appear 2 times and characters from b appear 1 time. Here is what I have :

from itertools import permutations, product

a='ABC'
b=['*', '%3A']
l=[a]*2+[b]

def g(list):
    for p in permutations(list):
        yield product(*p)


result=g(l)

So the problem I'm facing is that when I yield the result I got a nested iterator that is painful to use and when I use return it just returns the generator corresponding to only the first loop turn, just as if I did : g() only consisted of def g(): return product(*next(permutations(list))).


Solution

  • If you are python 3.3 or later you can use PEP 380: Syntax for Delegating to a Subgenerator ... just do yield from

    from itertools import permutations, product
    
    a='ABC'
    b=['*', '%3A']
    l=[a]*2+[b]
    
    def g(list):
        for p in permutations(list):
            yield from product(*p)
    
    
    result=g(l)