lambda 函式所引起的閉包問題

2021-08-11 06:54:53 字數 2416 閱讀 7972

之前在某本書上看到一道題,要求是:用字串sign中的每乙個字元去分割s字串,並得到最後的結果

s = 'ab;cd|efg|hi,jkl|mn\opq;rst,uvw/xyz'

sign = ';|\/,'

書中給的答案是這樣的:

def

my_split

(s, sign):

s = [s]

for i in sign:

t =

for x in s:

map(lambda x: t.extend(x.split(i)), s)

s = t

return s

print(my_split(s,sign))

按這邏輯推導了一遍,覺得這map, lambda用得高明,但是我一執行,結果竟然是,什麼鬼,說好的分割呢,全割沒了?

難道編輯器有問題?難道我寫錯**了,都不是,又重新推導了一遍,問題依舊!

然後我就按這種邏輯,自定義了乙個函式,只不過沒用map, lambda來實現:

def

my_split

(s, sign):

for i in sign:

t =

if type(s) is list:

for j in s:

t.extend(j.split(i))

else:

s = s.split(i)

t.extend(s)

s = t

return s

print(my_split(s,sign))

**是囉嗦了點,但是能正常執行,得到我想要的結果:

['ab', 'cd', 'efg', 'hi', 'jkl', 'mn', 'opq', 'rst', 'uvw', 'xyz']
既然這樣,那說明邏輯上沒有問題啊,那為什麼結果不對呢?

經過多方請教無果:

不得不重新一步一步推導,然後看到函式my_split內部的lambda函式,這種樣式不禁想到了閉包。就做了下面這樣乙個嘗試:

def

my_split

(s, sign):

s = [s]

for i in sign:

t =

for x in s:

#map(lambda x: t.extend(x.split(i)), s)

deflambd

(i, t, x, s):

map(t.extend(x.split(i)),s)

lambd(i, t, x, s) # 注意這行,這裡執行了lambd函式

s = t

return s

print(my_split(s,sign))

這裡將lambda函式那行注釋掉,重新定義了乙個lambd函式,做了兩樣的事,但是,因為加上了執行,最終我得到了想要的結果。

事實上,lambda函式也可以賦值給乙個物件,如:splits=lambda x: t.extend(x.split(i)),最後通過呼叫這個splits函式,達到執行的目的

但這樣就失去了lambda 匿名函式的作用,並且由於外面需要執行map方法,所以這裡是無法完成的。

最後,要說的就是,如上面定義的lamdb函式一樣,它引用了外部變數如i, t ,x,s,形成了閉包,但是,如果最後不呼叫lamdb(i,t,x,s),

每次只是產生 了乙個函式物件,並沒有執行。

這裡可以做這樣乙個測試:

def

my_split

(s, sign):

s = [s]

for i in sign:

t =

#map(lambda x: t.extend(x.split(i)), s)

for x in s:

deflambd

(i, t, x, s):

map(t.extend(x.split(i)),s)

#lambd(i, t, x, s) # 注釋掉

s = t

print(s) # 列印出來

return s

print(my_split(s,sign))

我們將函式執行語句注釋掉,然後每次內迴圈完成的時候列印s,結果發現每次s都是空列表。原因是lambd函式沒有執行,

所以t列表一直為空,每次內迴圈執行完成後,將t賦值給了s,導致s也一直為空,這就是為什麼最後得到的結果為空的原因。

這種lambda函式形成閉包比較隱蔽,如果沒仔細看,很容易忽略,所以一定要注意。

當然這裡更簡單的辦法是用正規表示式的re.split方法,一下字就可以搞定。

day12 閉包函式 匿名函式 lambda

閉包函式 閉包函式的定義 如果內函式使用了外函式的區域性變數 並且外函式把內函式返回出來的過程 叫做閉包 裡面的內函式是閉包函式 乙個簡單的閉包函式示例 def songyunjie family father 王健林 deff hobby print 這是我爸爸 format father 內函式...

Swift 閉包引起的記憶體溢位

swift 中由閉包引起的self強引用導致的記憶體溢位,必須使用unowned 無主引用 才能釋放,weak 弱引用 也不可 如下例項 必須在閉包ashtml中使用 unowned self in宣告self,這樣在最後釋放時,才能成功釋放掉paragraph物件。class htmlelemen...

函式閉包python中的閉包

本文純屬個人見解,是對前面學習的總結,如有描述不正確的地方還請高手指正 單簡說,閉包就是根據不同的置配息信到得不同的結果 再來看看專業的解釋 閉包 closure 是詞法閉包 lexical closure 的簡稱,是引用了由自變數的函式。這個被引用的由自變數將和這個函式一起存在,即使已離開了造創它...