Python語言的高級特性
 函數(shù)是編程(Functional Programming)
 - 基于lambda演算的一種編程方式 
- 程序中只有函數(shù)
 - 函數(shù)可以作為參數(shù),同樣可以作為返回值
 - 純函數(shù)式變成語言:LISP,Haskell
 
 - Python函數(shù)式編程只是借鑒函數(shù)式編程的一些特點(diǎn),可以理解成一般函數(shù)式一般Python
 - 需要講述 
- 高階函數(shù)
 - 返回函數(shù)
 - 匿名函數(shù)
 - 裝飾器
 偏函數(shù)
 lambda表達(dá)式
 - 函數(shù):最大程度復(fù)用代碼 
- 存在問題:如果函數(shù)很小,很短,則會(huì)造成啰嗦
 - 如果函數(shù)被調(diào)用次數(shù)少,則會(huì)造成浪費(fèi)
 - 對于閱讀者來說,造成閱讀流程的被迫中斷
 
 - lambda表達(dá)式(匿名函數(shù)): 
- 一個(gè)表達(dá)式,函數(shù)體相對簡單
 - 不是一個(gè)代碼塊,僅僅是一個(gè)表達(dá)式
 - 可以有參數(shù),有多個(gè)參數(shù)也可以,用逗號隔開
 
 
# lambda表達(dá)式的用法
# 1.以lamnda開頭
# 2.緊跟一定的參數(shù)(有的話)
# 3.參數(shù)后用冒號和表達(dá)式主題隔開
# 4.只是一個(gè)表達(dá)式,所以沒有return# 計(jì)算一個(gè)數(shù)字的100倍數(shù)
stm = lambda X: 100 * X
print(stm(89))stm2 = lambda x,y,z: x + y * 10 + z * 100
print(stm2(4,5,6)) 
高階函數(shù)
 - 把函數(shù)作為參數(shù)使用的函數(shù),叫高階函數(shù)
 
# 函數(shù)名稱是變量
# 函數(shù)名稱就是一個(gè)變量
# 既然函數(shù)名稱是變量,則應(yīng)該可以被當(dāng)做參數(shù)傳入另一個(gè)函數(shù)
'''
# 高階函數(shù)舉例
# funA是普通函數(shù),返回一個(gè)傳入數(shù)字的100倍數(shù)字
def funA(n):return n * 100
# 再寫一個(gè)函數(shù),把傳入?yún)?shù)乘以300倍,利用高階函數(shù)
def funB(n):# 最終是想返回300nreturn funA(n) * 3
print(funB(9))# 寫一個(gè)高階函數(shù)
def funC(n,f):# 假定函數(shù)是把n擴(kuò)大100倍return f(n) * 3
print(funC(9,funA)) 
系統(tǒng)高階函數(shù)-map
 - 原意就是映射,即把集合或者列表的元素,每一個(gè)元素都按照一定規(guī)則進(jìn)行操作,生成一個(gè)新的列表或者集合
 - map函數(shù)是系統(tǒng)提供的具有映射功能的函數(shù),返回值是一個(gè)迭代對象
 
# 利用map
l1=[i for i in range(11)]
print(l1)
def mulTen(n):return n*10
l3 = map(mulTen, l1)print(list(l3)) 
reduce
 - 原意是歸并,縮減
 - 把一個(gè)可迭代對象最后歸并成一個(gè)結(jié)果
 - 對于函數(shù)參數(shù)要去:必須由兩個(gè)參數(shù),必須有返回結(jié)果
 - reduce(函數(shù),列表)
 - reduce([1,2,3,4,5]) == f(f(f(f(1,2),3),4),5)
 - reduce需要導(dǎo)入functools包
 
from functools import reduce
# 定義一個(gè)操作函數(shù)
# 加入操作做函數(shù)只是相加def myAdd(x,y):return x * y
# 對于列表[1,2,3,4,5,6]執(zhí)行myAdd的reduce操作
rst = reduce(myAdd,[1,2,3,4,5])
print(rst) 
filter過濾函數(shù)
 - 過濾函數(shù):對一組數(shù)據(jù)進(jìn)行過濾,符合條件的數(shù)據(jù)會(huì)生成一個(gè)新的列表并返回
 - 跟map相比 
- 相同:都對列表的每一個(gè)元素逐一進(jìn)行操作
 - 不同: 
- map會(huì)生成一個(gè)跟原來數(shù)據(jù)相對應(yīng)的新隊(duì)列
 - filter不一定,只要符合條件的才會(huì)進(jìn)入新的數(shù)據(jù)集合
 
 - filter函數(shù)怎么寫 
- 利用給定函數(shù)進(jìn)行判斷
 - 返回值一定是個(gè)布爾值
 - 調(diào)用格式:filter(f,data),f是過濾函數(shù),data是數(shù)據(jù)
 
 
 
# filter案例
# 對于一個(gè)列表,對其進(jìn)行過濾,偶數(shù)組成一個(gè)新列表
# 需要定義過濾函數(shù)
# 過濾函數(shù)要求有輸入,返回布爾值
def isEven(a):return a % 2 == 0
l = [3,4,64,4322,6554,342,65,867]
rst = filter(isEven, l)
# 返回的filter內(nèi)容是一個(gè)可迭代對象
print(list(rst)) 
高階函數(shù)-排序sorted
 - 把一個(gè)序列按照給定算法進(jìn)行排序(升序)
 - key:在排序前對每一個(gè)元素key函數(shù)運(yùn)算,可以理解成按照key函數(shù)定義的邏輯進(jìn)行排序
 - python2和python3相差巨大
 
# 排序的案例a = [-21,321,432242,-4322,21,43,-564,2334]
al = sorted(a)
print(al)# 按照絕對值進(jìn)行排序
# abs是求絕對值的意思
# 即按照絕對值的倒序排序
a1 = sorted(a, key=abs, reverse=True)
print(a1)astr = ['dana', 'Danaa', 'jjc', 'wcx']
str1 = sorted(astr)
print(str1)str2 = sorted(astr, key=str.lower)
print(str2) 
返回函數(shù)
 - 函數(shù)可以返回具體的值
 - 也可以返回一個(gè)函數(shù)作為結(jié)果
 
# 定義一個(gè)普通函數(shù)
def myF(a):print('In myF')return None
a = myF(8)
print(a)    # 函數(shù)作為返回值返回,被返回的函數(shù)在函數(shù)體內(nèi)定義
def myF2():def myF3():print("In myF3")return 3return myF3# 使用上面定義
# 調(diào)用myF2,返回一個(gè)函數(shù)myF3,賦值給f3
f3 = myF2()
print(f3())def myF4( *args):def myF5():rst = 0for n in args:rst += nreturn rstreturn myF5
f5 = myF4(1,2,3,4,5,6,7)
print(f5()) 
閉包
 - 當(dāng)一個(gè)函數(shù)在內(nèi)部定義函數(shù),并且內(nèi)部的函數(shù)應(yīng)用外部函數(shù)的參數(shù)或者局部變量,當(dāng)內(nèi)部函數(shù)被當(dāng)做返回值的時(shí)候,相關(guān)參數(shù)和變量保存在返回的函數(shù)中,這種結(jié)果,叫閉包
 - 上面定義的myF4是一個(gè)標(biāo)準(zhǔn)閉包結(jié)構(gòu)
 
# 閉包常見坑
def count():# 定義列表fs = []for i in range(1,4):def f():return i*ifs.append(f)return fs
f1,f2,f3 = count()
print(f1())## 出現(xiàn)的問題:
- 造成上述狀況的原因是,返回函數(shù)引用了變量i,i并非立即執(zhí)行,而是等到三個(gè)函數(shù)都返回的時(shí)候才統(tǒng)一使用,此時(shí)i已經(jīng)變成了3,最終調(diào)用的時(shí)候,都返回的是3*3
- 此問題描述成:返回閉包時(shí),返回函數(shù)不能引用任何循環(huán)變量
- 解決方案:在創(chuàng)建一個(gè)函數(shù),用該函數(shù)的參數(shù)綁定循環(huán)變量的當(dāng)前值,無論該循環(huán)變量以后如何改變,已經(jīng)綁定的函數(shù)參數(shù)值不再改變def count1():def f(j):def g():return j*jreturn gfs =[]for i in range(1,4):fs.append(f(i))return fs
f1,f2,f3 = count1()
print(f1())
print(f2())
print(f3()) 
裝飾器(Decrator)
 - 在不改動(dòng)函數(shù)代碼的基礎(chǔ)上無限制擴(kuò)展函數(shù)功能的一種機(jī)制,本質(zhì)上講,裝飾器是一個(gè)返回函數(shù)的高階函數(shù)
 - 裝飾器的使用:使用@語法,即在每次要擴(kuò)展的函數(shù)定義前使用@+函數(shù)名
 
import time
# 高階函數(shù),以函數(shù)作為參數(shù)
def printTime(f):def wrapper(*args, **kwargs):print("Time:", time.ctime())return f(*args, **kwargs)return wrapper
# 上面定義了裝飾器,使用的時(shí)候需要用到@,此符號是python的語法糖
@printTime
def hello():print("Hello world")
hello()
# 裝飾器的好處是,一點(diǎn)定義,則可以裝飾任意函數(shù)
# 一旦被其裝飾,則把裝飾器的功能直接添加到定義函數(shù)的功能上
# 上面對函數(shù)的裝飾使用了系統(tǒng)定義的語法糖hello =printTime(hello)
hello()
 
偏函數(shù)
 - 參數(shù)固定的函數(shù),相當(dāng)于一個(gè)由特定參數(shù)的函數(shù)體
 - functools.partial的作用是,把一個(gè)函數(shù)某些函數(shù)固定,返回一個(gè)新函數(shù)
 
#
i = int("100E", base=32)
print(i)# 新建一個(gè)函數(shù),此函數(shù)是默認(rèn)輸入的字符串是16進(jìn)制數(shù)字
# 把次字符串返回十進(jìn)制的數(shù)字def int16(x, base=16):return int(x,base)
t = int16("12345")
print(t)import functools
# 實(shí)現(xiàn)上面int16的功能
int16 = functools.partial(int, base=16)
print(int16("12345")) 
zip
 - 把兩個(gè)可迭代內(nèi)容生成一個(gè)可迭代的tuple元素類型組成的內(nèi)容
 
l1 = [1,2,3,4,5,6,7]
l2 = [11,12,13,14,15,16]z = zip(l1,l2)
print(tuple(z)) 
enumerate
 - 跟zip功能比較像
 - 對可迭代對象里的每一個(gè)元素,配上一個(gè)索引,然后索引和內(nèi)容構(gòu)成tuple類型
 
l1 = [1,2,3,4,5,6,7]
em = enumerate(l1)
l3 = [i for i in em]
print(l3) 
collections模塊
 - namedtuple 
 - deque 
 - counter 
- 統(tǒng)計(jì)字符串個(gè)數(shù)
 
 
# cellections
import collections
Point = collections.namedtuple("point",['x', 'y'])
p = Point(11,22)
print(p.x)
print(p[0])Circle = collections.namedtuple("Circle", ['x', 'y', 'r'])
c = Circle(100,150,10)
print(c)# deque
from collections import dequeq = deque(['a', 'b', 'c'])
print(q)
q.append('d')
print(q)
q.appendleft('x')
print(q)# Counter
from collections import Counter
c = Counter('dghasjkdahduqahwfh')
print(c)s = ['jjc', 'jjc', 'jjc', 'sdaa', 'wsd', 'wcx', 'wcx']
d = Counter(s)
print(d) 
 
轉(zhuǎn)載于:https://www.cnblogs.com/rener0424/p/10420886.html
                            總結(jié)
                            
                                以上是生活随笔為你收集整理的12 - 函数式编程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
                            
                            
                                如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。