Archive for March 29, 2009

Python generator to list decorator

Python generators can be evil because of the implicit state they create. How many time have you done this:

items = get_items()
print list(items)
f(items, x)

It might prevent confusion if generators are only used when one needs lazy iteration (e.g when reading from files of unbounded size)

However, avoiding yield can be work: creating a list, appending to it several times, and then returning it is an effort. This is probably the reason that I use generators when I don’t need to.

One workaround is to create a python generator-to-list decorator like so:

def listify(gen):
    "Convert a generator into a function which returns a list"
    def patched(*args, **kwargs):
        return list(gen(*args, **kwargs))
    return patched

@listify
def f(x):
     for i in range(x):
        yield "item" + str(i)

assert f(5) == "item0 item1 item2 item3 item4".split()

One can also define a ‘dictate’ decorator as follows:

from functools import wraps

def dictate(func):
    @wraps(func)
    def patched(*args, **kwargs):
        return dict(*func(*args, **kwargs))
    return patched

This turns a generator that yields pairs (a_i, b_i) into the dictionary {a_i: b_i}.

Advertisements

March 29, 2009 at 3:42 pm Leave a comment


March 2009
M T W T F S S
« Feb   Apr »
 1
2345678
9101112131415
16171819202122
23242526272829
3031