1. 程式人生 > >零基礎入門Python3-函數式編程(3)

零基礎入門Python3-函數式編程(3)

先來 賦值 map 兩個 append 語法 順序 style for循環

一、返回函數

函數作為 "返回值" 返回。特點是返回函數在調用的時候才運行計算。

# 實例1,求傳入值的平方

def func(n):

def func1():

return n*n

return func1

print(func(2))

>>> <function func.<locals>.func1 at 0x00000000024CFA60>

在這個實例中,我們定義了兩個函數,func1 返回的是一個平方值,而 func 返回的是 func1 這個函數本身。當我們調用 func 這個函數的時候,返回的是函數 func1,但是並沒有計算出結果。

# 實例2,接上面的例子

#我們把func(2)賦值給變量 a,並且運行 a()

a=func(2)

print(a())

>>> 4

# 所以,只有運行 函數 a() 的時候,才會返回運算結果

我們來看一個返回函數的例子

# 實例3,返回1,2,3 的2倍的值

def func1():

ls=[]

for i in range(1,4):

def func2():

return i*2

ls.append(func2)

return ls

a1,a2,a3=func1()

print(a1())

print(a2())

print(a3())

>>> 6

6

6

# a1,a2,a3=func1(),這個是給這三個變量依次賦值,值為函數

# 按照我們的想法,這三個值應給為 2,4,6,為什麽結果成了6,6,6 了?這裏我們引入一個新的知識,這就是閉包。我們先不說解釋什麽是閉包,我們先來分析一下該函數的執行的順序以及過程。

# 實例3分析

def func1():

# 首先定義 func1 這個函數

ls=[]

# 接著定義 空的列表ls

for i in range(1,4):

# for循環,並分次把 1,2,3 賦值給變量 i

for i in range(1,4):

def func2():

return i*2

ls.append(func2)

return ls

# 紅色的部分為 for 循環的內部語句,for 循環的次數為3次。首先 for 每次循環都要創建新的函數 func2,函數的返回值為 變量 i * 2。函數創建完畢後,接著運行 ls.append(func2),添加的值為函數,並不是直接添加計算結果。for 循環完畢後,返回列表 ls。最後把函數 func1 的返回值分別賦值給 a1,a2,a3。

# 以上是程序的運行過程,我們接著來說內部的運行邏輯。當然,主要是紅色部分的代碼。

for i in range(1,4):

def func2():

return i*2

ls.append(func2)

# 首先,for 循環生成了 i=1 的變量,開始第一次循環,創建一個新的函數func2,接著運行ls.append(func2),向列表 ls 添加一個元素,這個元素是一個函數 fun2,但是函數並沒有運行起來,而是相當於 "掛" 起來了,就此第一次循環完畢。

# 接著第二次循環,i=2,創建一個新的函數 func2,接著想 ls 添加函數 func2,和第一次一樣,函數並沒有運行,第二次循環完畢。

# 第三次循環 i =3,創建一個新的函數 func2,接著想 ls 添加函數 func2,和第一次一樣,函數並沒有運行,第三次循環完畢。

# 這時候,for 循環完,i 的值為3。接著返回列表 ls 。這時,函數 func1 也已經定義完。

# 運行 a1,a2,a3=func1(),把列表 ls 中的三個函數分別賦值給a1,a2,a3

# 接著運行 print(a1()) print(a2()) print(a3()),這時候的a1,a2,a3已經是代表的三個對應的函數。此時,函數 func2才真正的運行起來了,可 i 的值已經為3了。所以三個函數的輸出值都為 6 。

# 函數的返回值為函數,且內部函數調用外部變量和參數的情況,稱為閉包。(我是這麽理解的==!見笑了),如果破解這種情況呢?我們看實例4

# 實例4,破解閉包

def func1():

ls=[]

for i in range(1,4):

def func2(j):

def func3():

return j*2

return func3

ls.append(func2(i))

return ls

a1,a2,a3=func1()

print(a1())

print(a2())

print(a3())

>>> 2

4

6

# 只需要再新建一個函數,把 for 循環的變量 i 的值,傳入新函數的參數中,然後就可以放心的調用參數了。

二、匿名函數

使用 lambda 創建一個匿名函數。語法如下

lambda 參數1、參數2......:語句

- 匿名函數沒有對應的函數變量,但可以自己指定變量

- 匿名函數只能有一個表達式

- 可以沒有參數,參數也可以是可變參數、關鍵字參數和命名關鍵字

# 實例5

print(list(map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9])))

>>> [1, 4, 9, 16, 25, 36, 49, 64, 81]

# 可以利用 map 函數來構建list,方便快捷

# 實例6,兩個參數,表達式為判斷語句

a =lambda x,y:True if x>y else False

print(a(2,3))

>>> False

# 把匿名函數賦值給變量 a,在使用 a 往匿名函數帶入參數

# 實例7,lambda 的可變參數

b=lambda *args:list(args)

print(b(1,2,3))

>>> [1, 2, 3]

# 事實證明,lambda 的參數也可以是可變參數

# 實例8,lambda 的關鍵字參數

c=lambda **kw:True if kw[‘name‘]==‘zhangsan‘ else False

print(c(name=‘zhangsan‘,age=18))

>>> True

# 在一次證明,關鍵字參數也是可以的

# 實例9,lambda 的命名關鍵字參數

d=lambda name,age,*,job :‘My name is ‘+name+‘, i am ‘+str(age)+", "+‘job is ‘+job

print(d(‘zhangsan‘,18,job=‘Study‘))

>>> My name is zhangsan, i am 18, job is Study

# 成功帶入命名關鍵字參數

# 綜上實例,我們可以看到,就參數而言,和正常函數是沒有什麽區別的。但是執行語句lambda只能有一個表達式,而正常函數是可以有很多的。

技術分享圖片

關註公眾號,了解更多!

零基礎入門Python3-函數式編程(3)