Python函数式编程

Python函数式编程,python,function,functional-programming,Python,Function,Functional Programming,我的问题是: 假设我们有3个函数:f,g,h和下面的代码 y = f(x) a = g(y) b = h(y) 我想在一行上做这件事,比如: a,b = g(f(x)),h(f(x)) 但是如果f非常慢(并且不缓存它的结果),那么这是没有效率的 我有一个发电机解决方案: a,b = ((g(y),h(y)) for y in (f(x),)).next() 但这不是很可读 我想做一些类似的事情: with f(x) as y: a,b = g(y),h(y) 有人有主意吗 (这是欺骗

我的问题是:

假设我们有3个函数:f,g,h和下面的代码

y = f(x)
a = g(y)
b = h(y)
我想在一行上做这件事,比如:

a,b = g(f(x)),h(f(x))
但是如果f非常慢(并且不缓存它的结果),那么这是没有效率的

我有一个发电机解决方案:

a,b = ((g(y),h(y)) for y in (f(x),)).next()
但这不是很可读

我想做一些类似的事情:

with  f(x) as y: a,b = g(y),h(y)
有人有主意吗

(这是欺骗

y = f(x);a = g(y);b = h(y)
)

代码

使用lambda。塔达!:

>>> def f(a):
...     return a+1
... 
>>> def g(a):
...     return a*2
... 
>>> def h(a):
...     return a*3
... 
>>> (lambda x: (g(x),h(x)))(1)
(2, 3)
>>> (lambda x: (g(x),h(x)))(f(1))
(4, 6)
>>> a,b=(lambda x: (g(x),h(x)))(f(1))
>>> a
4
>>> b
6

我可能没有抓住要点,但我看不出有什么问题

y = f(x); a,b = (g(y), h(y))
如果您在代码中经常执行此操作,并且追求的是简单性,那么您可能可以创建一个实用函数,将参数映射到函数列表:

def xmap(v, f_iter):
    "Subjects v to every function in f_iter and returns a list of results"
    return [f(v) for f in f_iter]
然后,您可以执行以下操作:

a, b = xmap(f(x), [g, h])  

map
习惯用法是众所周知的,因此这种方法可以说是可读的,也很容易理解,即
xmap()
类似于
map()
,但是使用了参数和函数的转置。

如果你想使用
with
语句,你可以用
f()
来修饰它并从中产生:

from contextlib import contextmanager

@contextmanager
def f(t):
    time.sleep(1)
    print 'f called'
    yield t

with f(1) as y:
    a, b = g(y), h(y)

只要做两行就行了。
y=f(x)有什么问题;a、 b=(g(y),h(y))
?您的第一个答案是正确的,但这不是函数式编程。这个问题只是为了好玩和深入学习python。
这不是函数编程。是的。不管怎样,我认为这是两行(或指令)。你的第一个答案是正确的,但这不是函数式编程。这个问题只是为了好玩,也是为了深入学习python。@user1129519很公平。我可以问你为什么要用Python做函数式编程吗?如果你在学习Python,你不应该把重点放在Python习语上,而不是放在其他范例上吗?Python支持多种编程范例,主要但不限于面向对象的、命令式的,以及(在较小程度上)函数式编程样式(wikipaedia),你为什么说
y=f(x);a、 b=(g(y),h(y))
不是函数式编程吗?如果f、g和h没有副作用,它符合范例。@joaquin我同意。我的陈述基于这样一个事实,即,因此不应该成为学习Python.imho的人的关注点,它既不比优秀的老
y=f(x)短,也不比老
y=f(x)更具可读性;a、 b=g(y),h(y)
“作弊”是的,很有趣,这就是为什么我没有投票。我只是一个评论(关于一个事实,通常更惯用的方法也是最简单的方法)。顺便说一句,变量和函数参数之间的等价性是一个在很多地方都会出现的经典模式。(如果必须进行Javascript异步编程,在实践中甚至非常有用)
from contextlib import contextmanager

@contextmanager
def f(t):
    time.sleep(1)
    print 'f called'
    yield t

with f(1) as y:
    a, b = g(y), h(y)