請教在這段語句中li = [lambda :x for x in range(10)]的步驟是怎樣的?

這段語句的執行是否是先循環得到10個lambda函數,在依次對lambda函數傳值。


實驗了下

方法如下:

1.修改代碼測試

得出引用的是同一個變數

2.反彙編

看到神奇的指令

3.調試查看

看到神奇的cell

順便看下fun本身

4.

查看剛才指令的源碼

所以差不多是這個

def fun():
_cell = [None]
li = []
_iter = iter(range(10))
for x in _iter:
_cell[0] = x
_a = lambda : _cell[0]
li.append(_a)

print [l() for l in li]

結論:

PS: 有大的公司招python的么,找工作..


是得到一個長度為10的數組,每個元素都是一個lambda,由於python的閉包特性,*每個*lambda的返回值都是 9(x最後的取值)。


[pattern for var in iterable] 是一個 List comprehension,它的作用是根據pattern(姑且這麼叫吧)和每一個var的值,生成一個新的值來構造一個list。在這裡,你的pattern是一個匿名函數,這個匿名函數沒有參數,每次調用它會返回一個x(注意,這裡有大坑)。

所以,這個表達式生成了一個list,list中每一個元素是一個匿名函數。既然它是函數,你就可以調用它:

for f in li:
print(f())

或者

list(map(lambda x: x(), li))

來調用每一元素。然後你會驚奇地發現,你得到一個 9, 9, ..., 9 ..........

一般來講,按照閉包的原則,調用函數時,只跟定義它的時候的環境有關(既當時綁定了哪些變數,定義了哪些函數),也就是 lexical scope 原則,所以你應該期望一個 [0, 1, ... , 9]。具體的討論見Python 中的 lambda 和「真正的」lambda 有什麼區別?


推薦閱讀:

如何將python list中每12項的平均值組成一個新的list?
python和C#結合的效果如何?是否能讓C#寫的程序調用python的庫?
自學python遇到如下問題如何解決?(主要有關模塊安裝的問題)
Python 用 * (重複運算符) 和迭代器生成 list 有何不同?
學習python有什麼用?python的實際應用有哪些?

TAG:Python | Python入門 |