2012-01-04 65 views
-2

有我的問題:Python的函數式編程

假設我們有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) 

代碼

import time 
def f(t): 
    time.sleep(1) 
    print 'f called' 
    return t 

def g(t): return 1 

def h(t): return 2 

a,b = g(f(x)),h(f(x)) 
a,b = ((g(y),h(y)) for y in (f(x),)).next() 
+7

只是使它2行。 – kennytm 2012-01-04 09:26:51

+2

'y = f(x); a,b =(g(y),h(y))'? – Marcin 2012-01-04 09:44:02

+0

你的第一個答案是正確的,但這不是函數式編程。這個問題只是爲了好玩並且深入學習python。 – user1129519 2012-01-04 10:04:04

回答

6

使用lambda。 TA-DAH !:

>>> 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 
+2

imho,這個既不短也不可讀,比舊的'y = f(x); a,b = g(y),h(y)''作弊「 – joaquin 2012-01-04 10:04:19

+0

當然不是,但它是對這個問題的回答:) – opqdonut 2012-01-04 11:41:49

+0

耶和一個有趣的,這就是爲什麼我沒有donwvoted它。我只是一個評論(關於這個事實,通常更習慣的方式也是最簡單的方式) – joaquin 2012-01-04 11:50:47

3

我可能錯過了點,在這裏,但我認爲沒有錯

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()但與指定參數和funcs中換位

+0

你的第一個答案是正確的,但這不是函數式編程。這個問題只是爲了好玩並且深入學習python。 – user1129519 2012-01-04 10:00:07

+1

@ user1129519不夠公平。請問爲什麼你要用Python做函數式編程?如果你在學習Python,你不應該專注於Pythonic成語而不是其他範式嗎? – 2012-01-04 10:04:42

+0

Python支持多種編程範例,主要但不限於面向對象,命令式,以及函數式編程風格(wikipaedia) – joaquin 2012-01-04 10:13:30

1

如果你想使用with語句,可以,只是裝飾用f()contextlib.contextmanager從它產生:

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) 
+0

謝謝你讓我發現新的python功能... – user1129519 2012-01-04 10:51:35