Python 函數式編程


 

函數式編程:允許把函數本身作為參數傳入另一個函數,還允許返回一個函數!

1.高階函數

一個函數可以接收另一個函數作為參數,這種函數稱之為高階函數

abs(-10)  是函數調用   abs是函數本身   abs函數名其實是一個變量名

變量可以指向函數,函數名也是變量名

 

map()

map(func,seq)函數接收兩個參數,一個是函數,一個是Iterable(可迭代對象,序列)map將傳入的函數func()依次作用到序列seq的每個元素,並把結果作為新的Iterator(迭代器)返回,之后可轉為lis或其他類型t輸出。

1 #!/usr/bin/python3
2 
3 def f(x):
4     return x*x
5 
6 r = map(f, [ 1, 2, 3, 4, 5, 6 ])
7 print(list(r))   
8 #由於結果r是Iterator(惰性序列),因此通過list()函數計算整個序列

 

reduce()

 reduce(func,seq)把一個函數作用在一個序列[x1, x2, x3, ...]上,這個函數必須接收兩個參數,reduce()把結果繼續和序列的下一個元素做累積計算,

意即一次取序列兩個元素放到函數,函數結果和下一個函數結果(取下兩個元素放到函數得到的函數結果)相加,依次類推。

1 #!/usr/bin/python3
2 from functools import reduce
3 
4 def f(x,y):
5     return x+y
6 
7 r = reduce(f, [ 1, 2, 3, 4, 5, 6 ])
8 print(r)

 

filter()

filter(func,seq)函數用於過濾序列,調用一個布爾函數func()來迭代遍歷每個seq中的元素,返回一個使func返回值為True的元素的序列

map()類似,filter()也接收一個函數和一個序列。和map()不同的是,filter()把傳入的函數依次作用於每個元素,然后根據返回值是True還是False決定保留還是丟棄該元素。

篩選回文      回數是指從左向右讀和從右向左讀都是一樣的數

1 #!/usr/bin/python3
2 
3 def is_palindrone(n):
4     return str(n) == str(n)[::-1]  #[::-1]是倒切 從右往左
5 
6 print( list( filter( is_palindrone, range(11,200) ) ) )

 

sorted()

排序的核心是比較兩個元素的大小。如果是數字,我們可以直接比較,但如果是字符串或者兩個dict呢?直接比較數學上的大小是沒有意義的,因此,比較的過程必須通過函數抽象出來。

sorted(seq,key=func)函數也是一個高階函數,它可以接收一個key函數來實現自定義的排序,例如按絕對值大小排序

 不是同一種類型數據相比較,key決定比較大小的標准:

 

匿名函數與lambda

lambda表達式返回可調用的函數對象

1 def add(x,y):return x+y
2 sum1 = add(2,3)
3 #等價於
4 add = lambda x,y:x+y
5 add(2,3)

 Python簡單的句法限制了lambda函數的定義體只能使用純表達式。即不能賦值,也不能使用while和try等Python語句

除了作為參數傳給高階函數之外,Python很少使用匿名函數

 

2.返回函數

把函數作為結果返回

 1 #!/usr/bin/python3
 2 
 3 def lazy_sum(*args):
 4     def sum():
 5     #閉包   sum可以引用外部函數lazy_sum的參數和局部變量
 6         ax = 0
 7         for n in args:
 8             ax = ax+n
 9         return ax
10     return sum
11     
12 f = lazy_sum(1, 3, 5, 7, 9)  #不需要立即求和,而是在后面的代碼中根據需要計算
13 #返回的函數並沒有立刻執行,而是直到調用了f()才執行
14 print(f())

返回值與函數類型

 返回的對象數目    Python實際返回的對象類型

  0            None

  1            object

  >1             tuple

 

 3.裝飾器

不修改原函數的定義,在代碼運行期間動態增加功能的方式(如在調用前后自動打印日志,但又不修改函數的定義),稱之為“裝飾器”(Decorator),裝飾器就是函數,借助@調用

 1 #!/usr/bin/python3
 2 
 3 def log(func):
 4     def printInfo(*arge, **kw):   #*不定長參數  **關鍵字參數
 5         print('call %s()' % func.__name__) #在調用func之前打印一些信息
 6         return func(*arge, **kw)
 7     return printInfo
 8 
 9 #log是一個裝飾器,接收函數返回函數,借助@語法把裝飾器置於函數的定義外
10 @log    #相當於執行了  now = log(now) 
11 def now():
12     print('2019-4-20')
13 
14 #現在同名now()指向了新的函數,調用now()返log()中的printInfo()函數
15 print(now())

 

4.偏函數

當函數參數過多,需簡化時,使用 functools.partial() 可以創建一個新的函數,這個函數可以固定住原函數的部分參數

1 #!/usr/bin/python3
2 import functools
3 
4 int2 = functools.partial(int, base = 2)
5 print(int2('1000000'))  #現在只需傳一個序列, 不需傳指定的進制

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM