2014-02-25 52 views
4

假設我有一個二維函數f(x,y)和另一個函數G(函數),它將函數作爲輸入。但是,G只將一維函數作爲輸入,而我想將第二個變量作爲固定參數傳給f。將函數作爲一個固定輸入的變量傳遞

現在,我只是宣佈第三個函數h將y設置爲一個設定值。這是它看起來像某種形式:

def f(x,y): 
    something something something 
    return z; 

def G(f): 
    something something something 

def h(x): 
    c= something 
    return f(x,c); 
G(h) 

在某些時候,我也使y我默認參數,每次我會改變。

這些都不是的可讀性,如果我在某種程度上能夠調用

G(f(x,c)) 

特定語法不起作用。做這個的最好方式是什麼?

+1

鑽營和部分應用是很好的話題進一步研究,如果你有興趣在函數式編程的支持。對於初學者,請參閱http://stackoverflow.com/questions/1352855/in-functional-programming-what-is-currying和http://stackoverflow.com/questions/218025/what-is-the-difference-between-currying -and-partial-application – roippi

回答

3

一個理想的解決方案將使用部分應用程序,但要做到這一點最快,最簡單的方法是將包裝f拉姆達聲明像這裏面:

G(lambda x: F(x, C)) 

的lambda語法基本上是創建一個接受匿名函數一個參數(這裏稱爲x並用該值x和常數C調用f。這工作,因爲C值被「俘獲」創建拉姆達時,它成爲拉姆達內局部常量。

+0

看看你的lambda中的x - 一個是大寫,另一個是小寫。 –

+0

@ChrisJohnson感謝您的發現。固定。 – ApproachingDarknessFish

1

試試這個:

def h(): 
    return lambda x: f(x,c) 

無需提供xh - 你可以傳遞一個函數,最終包裝,如果它不會在範圍內。事實上,h已經過時了,除非你想讓它以2個任意參數的函數工作:

def h(functionToWrap, fixedSecondArgument): 
    return lambda x: functionToWrap(x, fixedSecondArgument) 
4

functools.partial功能,可以用來做這個(注意,這是不完全清楚,其中c來自於你的示例代碼,所以我認爲這是一些常數)。

import functools 

def f(x,y): 
    return x+y 

c = 3 

G = functools.partial(f, c) 
G(4) 

我認爲這比迄今爲止建議的lambda方法更明確。

編輯:取代最右邊的參數是不可能的,因爲我們正在處理位置參數。根據控制的現有水平,你可以介紹其處理切換的包裝:

import functools 

def f(x,y): 
    return x+y 

def h(c,y): 
    return f(y,c) 

c = 3 

G = functools.partial(h, c) 
G(4) 

但我認爲你開始在這點犧牲可讀性和可維護性...

+0

+1。同意,這肯定比我的回答好。 – ApproachingDarknessFish

+0

是否可以替換右側的變量? – albiero

+0

由於局部處理位置參數,我不相信這是可能的。切換到關鍵字參數(部分也支持)將是一種解決方法。部分對象(http://docs.python.org/2/library/functools.html#partial-objects)確實暴露了參數,以便您可以操縱這些參數。取決於你擁有多少控制權,你可以創建一些中間功能來完成交換(參見編輯)。但是,所有這些都將以代碼可讀性和可維護性爲代價。 –

2

你在找什麼被稱爲封閉。

def make_h(c): 
    def h(x): 
     return f(x, c) 
    return h 

現在,如果您分配h = make_h(c),然後h(x)等於f(x, c),您可以您的H傳給G.

如果你願意,functools庫中有封閉(functools.partial

相關問題