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()`:

```
#!/usr/bin/pyton

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

And an example of use:

```
#!/usr/bin/pyton

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

value = source.next() # value is now: 2

source.send(value) # push it back

source.next() # again returns: 2
source.next() # returns: 3

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

```

1 comment: