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