亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

動態創建 lambda 函數列表,其中每個下一個函數使用前一個函數

動態創建 lambda 函數列表,其中每個下一個函數使用前一個函數

慕姐8265434 2022-05-24 10:12:45
我想創建lambdas一個給定大小n的列表(因此手動分配不起作用),其中每個元素取決于先前的函數并且它在列表中索引。我嘗試過各種類似的東西:n = 3func_list = [lambda x : 1]for k in range(1,n):    func_list.append(lambda x : func_list[k-1](x) * (x+k))print(list(map(lambda f : print(f(1)), func_list)))但在所有嘗試中,我都收到了關于recursion深度的錯誤消息:RecursionError                            Traceback (most recent call last)<ipython-input-296-f35123a830c4> in <module>      2 for k in range(1,3):      3     func_list.append(lambda x : func_list[k-1](x) * (x+k))----> 4 print(list(map(lambda f : print(f(1)), func_list)))<ipython-input-296-f35123a830c4> in <lambda>(f)      2 for k in range(1,3):      3     func_list.append(lambda x : func_list[k-1](x) * (x+k))----> 4 print(list(map(lambda f : print(f(1)), func_list)))<ipython-input-296-f35123a830c4> in <lambda>(x)      1 func_list = [lambda x : 1]      2 for k in range(1,3):----> 3     func_list.append(lambda x : func_list[k-1](x) * (x+k))      4 print(list(map(lambda f : print(f(1)), func_list))) ... last 1 frames repeated, from the frame below ...<ipython-input-296-f35123a830c4> in <lambda>(x)      1 func_list = [lambda x : 1]      2 for k in range(1,3):----> 3     func_list.append(lambda x : func_list[k-1](x) * (x+k))      4 print(list(map(lambda f : print(f(1)), func_list)))RecursionError: maximum recursion depth exceeded
查看完整描述

2 回答

?
斯蒂芬大帝

TA貢獻1827條經驗 獲得超8個贊

正如Elegant Odoo 的回答所指出的,Python lambdas 通過引用捕獲變量。


搜索答案時您可能會聽到的另一個術語是“后期綁定”,這意味著只有在執行 lambda 時才會將 lambda 內的變量綁定到它的實際值。結果,您創建的所有 lambda 函數都具有相同的(和最終的)值k,這會導致無限遞歸。


雖然exec基于 - 的方法是有效的,但我認為大多數人都會同意exec在實際代碼中應該避免這種做法。對此的替代解決方案是通過函數創建 lambda 函數以強制早期綁定:


n = 3

func_list = [lambda x: 1]


def create_fn(k_val):

    return lambda x: func_list[k_val - 1](x) * (x + k_val)


for k in range(1, n):

    func_list.append(create_fn(k))


print(list(map(lambda f: f(1), func_list)))

當您調用create_fnwith 時k, 的當前值將k傳遞給 name 下的函數k_val。然后k_val將 lambda 函數中的k_val變量綁定到 范圍內的變量,并在調用它時create_fn使用 的值。k


查看完整回答
反對 回復 2022-05-24
?
婷婷同學_

TA貢獻1844條經驗 獲得超8個贊

一個很好的案例來解釋 Reference 和 Value 之間的區別:


讓我解釋一下為什么會發生這種情況,以了解發生了什么讓我們使用普通函數,以便我們可以調試 K 的值:


    n = 3

    func_list = [lambda x : 1]

    for k in range(1,n):

        def f(x):

            print('K is: ', k)

            return func_list[k-1](x) * (x + k)

        func_list.append(f)


    # just print will be enough to cause error

    print(func_list[2])

輸出是:


    K is : 2

    K is : 2

    K is : 2

    K is : 2

    K is : 2

    ....

    ....

    ....

    ....

    RecursionError: maximum recursion depth exceeded while calling a Python object

您在所有方法中使用相同的變量(對 value 的引用)。K 引用循環生成的值 2。


在循環 make 結束后進行演示k = 5,這將引發錯誤index out of range。


一個簡單的解決方案exec:


    n = 3

    func_list = [lambda x: 1]

    for k in range(1, n):

        # here you are not using variable k we are using the value it's like

        # we are rewriting it to code every time but is not you who typing it's the compute -_^

        exec('func_list.append(lambda x : func_list[{k}-1](x) * (x + {k}))'.format(k=k))


    # lambda print(f(1)) will create [None, None, None] I removed the print

    print(list(map(lambda f: f(1), func_list)))

輸出:


    [1, 2, 6]

詛咒上述解決方案適用于您的情況,因為K它只是一個簡單Integer 的假設,K它是一個非常復雜的對象,具有復雜的屬性和私有變量。為了達到同樣的目的,您需要重建對象。


    # we need to consract another object using the value

    exec('... KClass({}, {}, {}) ...'.format(k.attr1, k.attr2, k.attr2))

KClass使用您的屬性 Object 的成像XClass將需要構造兩個 object k and x。


所以使用exec工廠模式是不實際的更好的方法來處理這個問題:


    n = 3

    func_list = [lambda x: 1]



    def method_factory(k):

        # here K reference it's not the same K reference that is created

        # in loop there are different but with the alias K

        return lambda x: func_list[k - 1](x) * (x + k)



    for k in range(1, n):

        func_list.append(method_factory(k))


    print(list(map(lambda f: f(1), func_list)))

為什么會這樣,因為當您調用method_factory它時,它將創建自己的范圍,其中包含一個帶有別名的引用,K該引用指向value的引用指向的引用相同。Kloop


希望你明白這一切都是關于reference和的scopes。


查看完整回答
反對 回復 2022-05-24
  • 2 回答
  • 0 關注
  • 134 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號