簡體   English   中英

在python中初始化lambda函數列表

[英]Initialising a list of lambda functions in python

我有一個函數元組,我想預加載一些數據。 目前,我執行此操作的方式如下。 本質上,我列出了新函數,並一次將lambda函數添加到其中,然后重新轉換為元組。 但是,當我在代碼的不同部分中使用這些函數時,它們中的每一個都表現得好像列表中的最后一個一樣。

def newfuncs(data, funcs):
    newfuncs = []
    for f in funcs:
        newf = lambda x: f(x, data)
        newfuncs.append(newf)
    return tuple(newfuncs)

這是問題的一個簡單例子

funcs = (lambda x, y: x + y, lambda a, b: a - b)
funcs = newfuncs(10, funcs)
print(funcs[0](5))
print(funcs[1](5))

我希望打印的數字是15,然后是-5。 但是,此代碼兩次打印數字-5。 如果有人可以幫助我了解為什么會這樣,將不勝感激。 謝謝!

如前所述,問題出在變量f ,該變量是分配給所有 lambda函數的相同變量,因此在循環結束時, 每個 lambda看到相同的f

解決方案是使用functools.partial或為lambda創建一個有范圍的默認參數:

def newfuncs(data, funcs):
    newfuncs = []
    for f in funcs:
        newf = lambda x, f=f: f(x, data)   # note the f=f bit here
        newfuncs.append(newf)
    return tuple(newfuncs) 

現在像以前一樣調用這些lambda可以得到:

15
-5

如果您使用的是python3.x,請確保查看ShadowRanger的注釋,這是有范圍的默認arg方法的一項可能的安全功能。

這是眾所周知的Python“問題”,或者我應該說“這就是Python的方式”。

您創建了元組:

( x => f(x, data), x => f(x, data) )

但是f是什么? f直到您最終調用函數才被評估!

首先, f(x, y)=>x+y 然后在您的for循環中,將f重新分配給 (x, y)=>xy

當您終於開始調用函數時,只有在那時,才會查找f的值。 此時f的值是多少? 所有函數的值是(x, y)=>xy 您的所有功能都會相減。 這是因為重新分配了f 只有一個f 並且在調用任何lambda之前,將那個且只有一個f值設置為減法函數。

附錄

如果有人感興趣,則不同的語言會以不同的方式處理此問題。 JavaScript在這里相當有趣(有些人會說混淆),因為它以Python方式執行操作,OP認為這是出乎意料的,以及OP可能期望的另一種方式。 在JavaScript中:

> let funcs = []
> for (let f of [(x,y)=>x+y, (x,y)=>x-y]) {
    funcs.push(x=>f(x,10));
  }
> funcs[0](5)
15
funcs[1](5)
-5

但是,如果將let更改為上面的var ,它的行為類似於Python,並且兩者都得到-5! 這是因為使用let ,對於for循環的每次迭代,您都會獲得不同的f 使用var ,整個函數共享相同的f ,並且不斷被重新分配。 這就是Python的工作方式。

cᴏʟᴅsᴘᴇᴇᴅ向您展示了您要執行的操作的方法是確保每次迭代獲得不同的f ,Python允許您以一種非常簡潔的方式進行操作,將lambda的第二個參數默認為該迭代的局部f 這很酷,因此如果有幫助,應該接受他們的回答。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM