Base case of recursive generator: yield or return

Viewed 200

Why is there a difference between using return and yield in a recursive generator's base case?

As a simple example, this function uses yield and does what I want (Cartesian product):

def product(x):
        if not x:
            yield tuple()
        else:
            head, *tail = x
            for i in head:
                for j in product(tail):
                    yield (i, ) + j

g = product([[1, 2], [3, 4], [5, 6]])
print([i for i in g])

#[(1, 3, 5), (1, 3, 6), (1, 4, 5), (1, 4, 6), (2, 3, 5), (2, 3, 6), (2, 4, 5), (2, 4, 6)]

However, after changing yield tuple() to return tuple(), what I get is an empty list:

def product(x):
        if not x:
            return tuple()
        else:
            head, *tail = x
            for i in head:
                for j in product(tail):
                    yield (i, ) + j

g = product([[1, 2], [3, 4], [5, 6]])
print([i for i in g])

#[]

Writing return [tuple()] does not do the trick either:

def product(x):
        if not x:
            return [tuple()]
        else:
            head, *tail = x
            for i in head:
                for j in product(tail):
                    yield (i, ) + j

g = product([[1, 2], [3, 4], [5, 6]])
print([i for i in g])

#[]
0 Answers
Related