Thursday, February 12, 2015

a backtracking python generator

I love python's `generator`s and needed a backtracking generator to help me out with a YAML parser that I am writing. This is possible using the `send` function, but the documentation and examples are a bit confusing for what I wanted. So I can find this next time I need it, here is a sample generator that  will cycle over anything that is iterable (e.g.: arrays, dicts, files), and all you to push things back using `send()`:


def testGen(source):
    backlines = []
    for line in source:
        backline = None
        usedLine = False
        while usedLine is False or backlines:
            if backlines:
                backline = yield backlines.pop()
                usedLine = True
                backline = yield line
            while backline: # loops returning None for every send()
                backline = yield None

And an example of use:


source = testGen([1, 2, 3]) # returns: 1

value = # value is now: 2

source.send(value) # push it back # again returns: 2 # returns: 3

source.send(4) # the value does not actually have to be from it # returns: 4