偶爾看到python的乙個經典坑:
flist =
[lambda
:i for i in
range(5
)]for f in flist():
print
(f()
)
按照一般邏輯,結果應該是 0 1 2 3 4
但執行結果是
444
44
查了一下,主要是變數作用域問題和函式執行的問題。
出現這種情況的主要原因是,迴圈在python中不形成作用域。也就是說,i不僅僅在for迴圈內有效,for迴圈結束後i依然可以被使用,即迴圈結束後,i=4
比如說,如果這樣寫:
flist = [lambda :i for i in range(5)]
del i
flist[0]()
就會報錯
nameerror traceback (most recent call last)
in ()
1 flist = [lambda :i for i in range(5)]
----> 2 del i
3 flist[0]()
nameerror: name 'i' is not defined
因為把i刪除了之後,lambda就沒辦法找到返回值i了。
然後,只有函式在被呼叫的時候才執行函式內部的東西,也就是說,在遍歷flist的時候,每呼叫乙個f,lambda :i 被執行一次,但記住這時候i=4,所以所有f都返回4。
要想達到預期效果,可以稍微修改一下:
flist =
[lambda x=i: x for i in
range(5
)]for f in flist:
print
(f()
)
輸出結果
012
34
為什麼這樣就可以了呢?先看下面:
flist=
for i in
range(5
):deffunc()
: x = i
return x
flist[0]
()
輸出結果是0。這段**和上面是等價的。可以看到,i 的值此時被傳遞進了函式,也就是說,每乙個 func 中都有 i值。等到迴圈結束,flist中的函式元素被呼叫的時候,因為 i 值在迴圈的時候已經成了每個func函式中的區域性變數,也就是0 1 2 3 4,所以flist0=0。 python的變數作用域問題
偶然掉進了乙個坑里。仔細分析了下原因。原來是變數作用域的問題。簡單抽象如下 id 1 許多行 id for id in range 10 許多行 if id 1 做一些事情 pass else 做另外一些事情 結果由於id在 id for id in range 10 中受到了影響發生了變化,導致蟲...
變數作用域問題
2018 04 09 首先一定要明白乙個問題,那就是你py程式裡面的變數作用域問題。因為你程式是工作在乙個分布式機器上的,那麼這些個資料就會分布在不同的機器上,或者說container上。要明確spark的工作架構,各個不同的工作身份。那麼乙個變數他是不是在不同的機器執行,他是不是最後會彙總到我們的...
python變數作用域
變數作用域 scope 在python中是乙個容易掉坑的地方。什麼是作用域 作用域簡單說就是乙個變數的命名空間。中變數被賦值的位置,就決定了哪些範圍的物件可以訪問這個變數,這個範圍就是命名空間。python賦值時生成了變數名,當然作用域也包括在內。python的作用域一共有4中,分別是 l loca...