How to map or nest Python 2.7 function generators? -
if have simple (although possibly complex) function generator in python 2.7, so:
def accumulator(): x = yield 0 while true: x += yield x
which can used, so:
>>> = accumulator() >>> a.send(none) 0 >>> a.send(1) 1 >>> a.send(2) 3 >>> a.send(3) 6
what simple wrapper function generator produces same result, except multiplied 2? above function generator simple, please assume complicated copy-paste. i'm trying something, like:
def doubler(): = accumulator() a.send(none) y = yield 0 while true: y = 2 * a.send(yield y)
or, imagining simpler:
def doubler(): = accumulator() a.send = lambda v: 2 * super(self).send(v) return
both of horribly broke, won't share syntax errors, may illustrate i'm trying do.
ideally, something, like:
>>> d = doubler() >>> d.send(none) 0 >>> d.send(1) 2 >>> d.send(2) 6 >>> d.send(3) 12
the results exact same original, except doubled.
i'm trying avoid duplicating complicated function generator create identical result, except scaled known factor.
the second generator have different input stream, cannot use result first generator , double it. need second independent generator, wrapping first.
the input stream indeterminate, such impossible generate entire sequence , transform.
it seems want map or nest these function generators, i'm not sure of appropriate jargon, , i'm getting in google.
if need have same interface coroutine (i.e. have send
method), brenbarn's solution simple gets.*
if can have different interface, higher-order function simpler:
def factor_wrapper(coroutine, factor): next(coroutine) return lambda x, c=coroutine, f=factor: f * c.send(x)
you use follows:
>>> = accumulator() >>> a2 = factor_wrapper(a, 2) >>> print a2(1) 2 >>> print a2(2) 6 >>> print a2(3) 12
*actually can shave several lines off make 4 lines total, though not reducing complexity much.
def doubler(a): y = yield next(a) while true: y = yield (2 * a.send(y))
or shorter...
def doubler(a, y=none): while true: y = yield 2 * a.send(y)
either of above can used follows:
>>> = accumulator() >>> a2 = doubler(a) >>> print a2.send(none) # alternatively next(a2) 0 >>> print a2.send(1) 2 >>> print a2.send(2) 6 >>> print a2.send(3) 12
Comments
Post a Comment