python當中的坑 閉包與lambda

2022-08-19 12:00:17 字數 1573 閱讀 2850

先來看乙個栗子:

def create():

return [lambda x:i*x for i in range(5)]

for i in create():

print(i(2))

結果:

888

88

create函式的返回值時乙個列表,列表的每乙個元素都是乙個函式 -- 將輸入引數x乘以乙個倍數i的函式。預期的結果時0,2,4,6,8. 但結果是5個8,意外不意外。

由於出現這個陷阱的時候經常使用了lambda,所以可能會認為是lambda的問題,但lambda表示不願意背這個鍋。問題的本質在與python中的屬性查詢規則,legb(local,enclousing,global,bulitin),在上面的例子中,i就是在閉包作用域(enclousing),而python的閉包是 遲繫結 , 這意味著閉包中用到的變數的值,是在內部函式被呼叫時查詢得到的

解決辦法也很簡單,那就是變閉包作用域為區域性作用域。

def create():

return [lambda x, i=i:i*x for i in range(5)]

for i in create():

print(i(2))

換種寫法:

def create():

a =

for i in range(5):

def demo(x, i=i):

return x*i

return a

for i in create():

print(i(2))

以上兩種寫法是一樣的

結果:

024

68

再來乙個問題相似的栗子

**很簡單:(宣告:python3問題)

nums = range(2,20)

for i in nums:

nums = filter(lambda x: x==i or x%i, nums)

print(list(nums))

結果:

[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

同樣按照正常的邏輯結果應該為:

[2, 3, 5, 7, 11, 13, 17, 19]

問題產生的原因:

修改**:

nums = range(2,20)

for i in nums:

nums = filter(lambda x,i=i: x==i or x%i, nums)

print(list(nums))

結果:

[2, 3, 5, 7, 11, 13, 17, 19]

更多python基礎教程---_<_>_----

更多python-re模組----_<_>_----

更多深入元類介紹----_<_>_----

linux--top命令詳解----_<_>_----

OC當中的閉包

oc當中閉包的基本定義 int sumblock int,int 隨後定義其具體的實現方式 int sumblock int,int int a,int b 關於swift 和oc中閉包的區別 可以看這個部落格 目前個人也不是很看得懂。隨後oc當中的閉包 是會捕獲外部的變數的,但不會對其進行修改,若...

python怎麼閉包 python的閉包

一 思考乙個問題 我們要給定乙個x,要求一條直線上x對應的y的值。公式是y kx b。我們需要用k,b來確定這條直線,則我們實現的函式應該有3個引數 defline k,b,x print k x b line 1,3,4 line 1,3,5 line 1,3,6 可以看到,我們每次修改x都要重新...

python 閉包 Python中的閉包

一 什麼是閉包 在談之前,我們先來說說作用域,變數的作用域無非就兩種 全域性變數和區域性變數。函式內部可以直接讀取全域性變數,但是在函式外部無法讀取函式內部的區域性變數。出於種種原因,我們有時候需要獲取到函式內部的區域性變數。但是,正常情況下,這是辦不到的!只有通過變通的方法才能實現。於是就引入了閉...