2014-12-13 26 views
2

下面的表達式實際上做了什麼?請幫我翻譯下面的lambda到人類語言

list = [lambda n=n: lambda x: x+n for n in range(10)] 

更具體地說:

  1. 是什麼n=n意思?
  2. 'list'將會是什麼內容?
  3. 會是怎樣的

    print(list[0](14))print(list[0]()(14))

,爲什麼輸出?

+2

與其問問輸出是什麼,爲什麼不嘗試呢? – 2014-12-13 08:39:01

+0

跑吧。 「爲什麼?」是真正的麻煩... – user3115040 2014-12-13 08:50:24

回答

3
  1. n=n是什麼意思?

lambda允許您定義帶參數,就像def功能。這些參數可以有default argument values。所以,lambda n=n:def foo(n=n):相同。

事實上,當面對那太複雜,你讀一個表達式,它往往是值得拆包成簡單的語句:

list = [] 
for n in range(10): 
    def spam(n=n): 
     def eggs(x): 
      return x+n 
     return eggs 
    list.append(spam) 

現在,爲什麼你想創建一個名爲n參數默認值爲n?爲什麼不只是lambda:The official FAQ解釋了這一點,但我們試着總結一下。

如果你只是寫:

funcs = [lambda: n for n in range(10)] 

...你得到的是沒有參數的10個功能,是在同一個變量,n所有關閉。因爲n具有在循環,調用時結束值9,他們都將返回9

但是,如果你這樣做:

funcs = [lambda n=n: n for n in range(10)] 

...你得到的是10個功能一個可選參數n(隱藏關閉n的視圖),其默認值是在定義每個函數時的值n。所以,當沒有參數調用時,第一個將返回0,第二個1,依此類推。

在你的情況下,當然,函數不只是返回n,它們返回一個函數,它接受一個參數,給它添加n,並返回結果。但這個想法是一樣的;你希望他們返回不同的功能,裏面加0,1,... 9到他們的論點,並非所有的返回等於功能,所有添加9.


  • 什麼會是list的內容?
  • list將是一個任選的參數,其默認值範圍從0到9,其中的每一個返回參數的函數的10個函數。該返回函數是來自外部函數的關於n的值的閉包。所以,當它被調用時,它返回其參數,x,加上n變量的範圍從0到9


  • 將什麼的
  • 輸出
    print(list[0](14)) 
    

    在這裏,你調用第一外功能,list[0],用參數14因此,而不是它的默認值0 n,它將會有14個。所以,你會得到的是一個函數,它帶有一個參數並將14加到它。但它會打印出像:

    <function <listcomp>.<lambda>.<locals>.<lambda> at 0x105f21f28> 
    

    這混亂長的Python是試圖3.4+要告訴你在哪裏可以找到函數的定義有所幫助。 通常是,當一個函數深深嵌套時,沿途的大多數步驟都有名稱。在這種情況下,你已經有了一個匿名函數三層,所以沒有名字都是非常有用的...

    爲了看它做任何有用的事情,你必須把它叫做:

    print(list[0](14)(20)) 
    

    這會給你34

    您也可以使用inspect模塊或dir來查找函數內部。例如,print(list[0](14).__code__.co_freevars[0], list[0](14).__closure__[0].cell_contents)會告訴你,它的內部函數使用名稱爲n的數字爲14。

    ...

    print(list[0]()(14)) 
    

    在這裏,你又打電話list[0],但這次不帶參數,所以其n得到的0默認值。因此,它返回一個函數,將0添加到它的參數。然後你用14調用該函數,所以你得到14

    +0

    Perfecto!謝謝。 – user3115040 2014-12-13 09:09:33

    0

    先回答最後一部分:

    In [1]: list = [lambda n=n: lambda x: x+n for n in range(10)] 
    
    In [2]: print(list[0](14)) 
    <function <lambda> at 0x7f47b5ca7cf8> 
    
    In [3]: print(list[0]()(14)) 
    14 
    

    獲得通過運行代碼。 list不好的名字的方式,因爲列表是一個Python內置的給你10個lambda函數,做的不多 - 第一個將返回原始參數x,第二個參數+ 1等。因爲n被存儲爲該lambda本地的lambda的索引n = n。