如何映射或嵌套Python 2.7函数生成器? [英] How to map or nest Python 2.7 function generators?

查看:47
本文介绍了如何映射或嵌套Python 2.7函数生成器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我在Python 2.7中有一个非常简单(尽管可能非常复杂)的函数生成器,如下所示:

If I have a very simple (although possibly very complex) function generator in Python 2.7, like so:

def accumulator():
    x = yield 0
    while True:
        x += yield x

可以使用哪个,就像这样:

Which can be used, like so:

>>> a = accumulator()
>>> a.send(None)
0
>>> a.send(1)
1
>>> a.send(2)
3
>>> a.send(3)
6

除了乘以2之外,另一个产生相同结果的函数生成器将是一个简单的包装器吗?上面的函数生成器很简单,但是请假定它太复杂而无法复制粘贴.我正在尝试一些东西,例如:

What would be a simple wrapper for another function generator that produces the same result, except multiplied by 2? The above function generator is simple, but please assume it is too complicated to copy-paste. I'm trying something, like:

def doubler():
    a = accumulator()
    a.send(None)
    y = yield 0
    while True:
        y = 2 * a.send(yield y)

或者,想象一些简单的事情:

Or, imagining something simpler:

def doubler():
    a = accumulator()
    a.send = lambda v: 2 * super(self).send(v)
    return a

这两者都被严重破坏了,所以我不会分享语法错误,但这可能说明了我正在尝试做的事情.

Both of which are horribly broke, so I won't share the syntax errors, but it may illustrate what I'm trying to do.

理想情况下,我想得到一些东西,例如:

Ideally, I would like to get something, like:

>>> d = doubler()
>>> d.send(None)
0
>>> d.send(1)
2
>>> d.send(2)
6
>>> d.send(3)
12

除了翻倍之外,结果与原始结果完全相同.

The results are the exact same as the original, except doubled.

我试图避免复制非常复杂的函数生成器以创建相同的结果,只是按已知因子进行缩放.

I'm trying to avoid duplicating a very complicated function generator to create an identical result, except scaled by a known factor.

第二个生成器最终将具有不同的输入流,因此我不能仅使用第一个生成器的结果并将其加倍.我需要第二个独立的生成器,包装第一个.

The second generator will ultimately have a different input stream, so I cannot just use the result from the first generator and double it. I need a second independent generator, wrapping the first.

输入流是不确定的,因此不可能生成整个序列然后进行转换.

The input stream is indeterminate, such that it is impossible to generate the entire sequence and then transform.

似乎我想映射或嵌套这些函数生成器,但是我不确定合适的术语,因此在Google中无处可寻.

It seems I want to map or nest these function generators, but I'm not sure of the appropriate jargon, and so I'm getting nowhere in Google.

推荐答案

如果您需要与协程具有相同的接口(即具有send方法),那么BrenBarn的解决方案可能会变得非常简单.*

If you need to have the same interface as a coroutine (i.e. have a send method), then BrenBarn's solution is probably as simple as it gets.*

如果您可以使用略有不同的界面,那么高阶函数会更简单:

If you can have a slightly different interface, then a higher-order function is even simpler:

def factor_wrapper(coroutine, factor):
    next(coroutine)
    return lambda x, c=coroutine, f=factor: f * c.send(x)

您将按以下方式使用它:

You would use it as follows:

>>> a = accumulator()
>>> a2 = factor_wrapper(a, 2)
>>> print a2(1)
2
>>> print a2(2)
6
>>> print a2(3)
12

*实际上,您可以减少几行以使其总共达到4行,尽管并没有真正降低复杂性.

*Actually you can shave several lines off to make it 4 lines total, though not really reducing complexity much.

def doubler(a):
    y = yield next(a)
    while True:
        y = yield (2 * a.send(y))

或更短...

def doubler(a, y=None):
    while True:
        y = yield 2 * a.send(y)

以上任何一种都可以按如下方式使用:

Either of the above can be used as follows:

>>> a = 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

这篇关于如何映射或嵌套Python 2.7函数生成器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆