Python Language Generators Refactoring list-building code


Suppose you have complex code that creates and returns a list by starting with a blank list and repeatedly appending to it:

def create():
    result = []
    # logic here...
    result.append(value) # possibly in several places
    # more logic...
    return result # possibly in several places

values = create()

When it's not practical to replace the inner logic with a list comprehension, you can turn the entire function into a generator in-place, and then collect the results:

def create_gen():
    # logic...
    yield value
    # more logic
    return # not needed if at the end of the function, of course

values = list(create_gen())

If the logic is recursive, use yield from to include all the values from the recursive call in a "flattened" result:

def preorder_traversal(node):
    yield node.value
    for child in node.children:
        yield from preorder_traversal(child)