【Python】编程笔记5
文章目錄
- 函數(shù)式編程(Functional Programming)
- 一、高階函數(shù)(Higher-order function)
- 二、map/reduce
- 1、map() 函數(shù)
- 2、reduce() 函數(shù)
- 三、filter
- 1、用 filter 求素?cái)?shù)
- 四、sorted
- 1、數(shù)字
- 2、字符串
- 五、返回函數(shù)
- 1、函數(shù)作為返回值
- 2、閉包
- 3、匿名函數(shù)
- 4、裝飾器
- 5、偏函數(shù)
- 模塊
- 1、使用模塊
- 2、作用域
- 3、第三方庫(kù)
函數(shù)式編程(Functional Programming)
函數(shù)式編程:思想更接近于數(shù)學(xué)計(jì)算,抽象程度很高的編程范式,純粹的函數(shù)式編程語(yǔ)言編寫的函數(shù)沒有變量。
特點(diǎn):允許把函數(shù)本身作為參數(shù)傳入另一個(gè)函數(shù),還允許返回一個(gè)函數(shù)。
Python 允許使用變量,因此,Python 不是純函數(shù)式編程語(yǔ)言。
一、高階函數(shù)(Higher-order function)
函數(shù)本身也可以賦值給變量,即:變量可以指向函數(shù)。例如:函數(shù)名。
f = abs print(f(-10))輸出結(jié)果
10高階函數(shù):一個(gè)函數(shù)就可以接收另一個(gè)函數(shù)作為參數(shù)。(既然變量可以指向函數(shù),函數(shù)的參數(shù)能接收變量)
def add(x, y, f):return f(x) + f(y)print(add(-5, 6, abs))輸出結(jié)果
11二、map/reduce
Python 中內(nèi)建了 map() 和 reduce() 函數(shù)。
1、map() 函數(shù)
map()函數(shù):接收兩個(gè)參數(shù),一個(gè)是函數(shù),一個(gè)是 Iterable。map 將傳入的函數(shù)依次作用到序列的每個(gè)元素,并把結(jié)果作為新的 Iterator 返回。
def f(x):return x * x r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9]) print(list(r))## 把這個(gè) list 所有數(shù)字轉(zhuǎn)為字符串 print(list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9])))輸出結(jié)果
[1, 4, 9, 16, 25, 36, 49, 64, 81] ['1', '2', '3', '4', '5', '6', '7', '8', '9']2、reduce() 函數(shù)
reduce()函數(shù):把一個(gè)函數(shù)作用在一個(gè)序列 [x1, x2, x3, ...] 上,這個(gè)函數(shù)必須接收兩個(gè)參數(shù), reduce 把結(jié)果繼續(xù)和序列的下一個(gè)元素做累積計(jì)算,其效果就是:
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)把序列[1, 3, 5, 7, 9]變換成整數(shù) 13579 的 reduce 實(shí)現(xiàn):
from functools import reduce def fn(x, y):return x * 10 + y print(reduce(fn, [1, 3, 5, 7, 9]))輸出結(jié)果
13579str 類型 ==》int 類型
from functools import reduce def str2int(s):def fn(x, y):return x * 10 + ydef char2num(s):return {'0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9}[s]return reduce(fn,map(char2num,s))# 13579 print(str2int('13579'))利用 lambda 函數(shù)進(jìn)一步簡(jiǎn)化:
def char2num(s):return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s] def str2int(s):return reduce(lambda x,y:10 * x + y, map(char2num, s))str ==》float
def str2float(s):def char2num(s):return {'0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9}[s]def fnMuti(x, y):return 10 * x + ydef fnDivid(x, y):return x / 10 + ydotIndex = s.index('.')return reduce(fnMuti, map(char2num, s[:dotIndex])) + reduce(fnDivid, list(map(char2num, s[dotIndex + 1:]))[::-1])/10 print('str2float(\'123.456\') =', str2float('123.456'))輸出結(jié)果
str2float('123.456') = 123.456三、filter
filter() 函數(shù)用于過(guò)濾序列。接收兩個(gè)參數(shù):一個(gè)函數(shù)和一個(gè)序列,filter() 把傳入的函數(shù)依次作用于每個(gè)元素,然后根據(jù)返回值是 True ,則保留,為 False 則丟棄該元素。
def is_odd(n):return n % 2 == 1 print(list(filter(is_odd, [1,2,4,5,6,9,10,15]))) # 結(jié)果: [1, 5, 9, 15]==》filter() 函數(shù)返回結(jié)果是 Iterator,是一個(gè)惰性序列,需要使用 list() 函數(shù)獲取所有的結(jié)果并返回 list。
1、用 filter 求素?cái)?shù)
實(shí)現(xiàn)方法:埃氏篩法。列出從 2 開始的所有自然數(shù),構(gòu)造一個(gè)序列:取序列第一個(gè)數(shù)并篩掉其的倍數(shù),依次類推…
# 生成器,且是一個(gè)無(wú)限序列 def _odd_iter():n = 1while True:n = n + 2yield n# 過(guò)濾函數(shù) def _not_divisible(n):return lambda x : x % n > 0# 用于不斷返回素?cái)?shù)的生成器 def primes():yield 2it = _odd_iter() # 初始序列while True:n = next(it)yield nit = filter(_not_divisible(n), it) # 構(gòu)造新的序列# 設(shè)置一個(gè)退出循環(huán)的條件 for n in primes(): if n < 1000:print(n)else:break四、sorted
通常規(guī)定,對(duì)于兩個(gè)元素 x 和 y,如果認(rèn)為 x < y,則返回-1,如果認(rèn)為 x == y,則返回 0,如果認(rèn)為 x > y,則返回 1
1、數(shù)字
## 原始 print(sorted([36, 5, -12, 9, -21])) ## sorted()函數(shù)也是一個(gè)高階函數(shù),它還可以接收一個(gè) key 函數(shù)來(lái)實(shí)現(xiàn)自定義的排序。 ## key 指定的函數(shù)將作用于 list 的每一個(gè)元素上,并根據(jù) key 函數(shù)返回的結(jié)果進(jìn)行排序。 print(sorted([36, 5, -12, 9, -21], key=abs))輸出結(jié)果
[-21, -12, 5, 9, 36] [5, 9, -12, -21, 36]2、字符串
## 默認(rèn)情況下,對(duì)字符串排序,是按照 ASCII 的大小比較的 print(sorted(['bob', 'about', 'Zoo', 'Credit'])) ## 可實(shí)現(xiàn)忽略大小寫的排序 print(sorted(['bob', 'about', 'Zoo', 'Credit'], key = str.lower)) ## reverse 為 true 表示反向排序 print(sorted(['bob', 'about', 'Zoo', 'Credit'], key = str.lower, reverse = True))輸出結(jié)果
['Credit', 'Zoo', 'about', 'bob'] ['about', 'bob', 'Credit', 'Zoo'] ['Zoo', 'Credit', 'bob', 'about']五、返回函數(shù)
1、函數(shù)作為返回值
例如:返回求和的函數(shù)
def lazy_sum(*args):def sum():ax = 0for n in args:ax = ax + nreturn axreturn sum f1 = lazy_sum(1,3,5,7,9) f1 f1() # 函數(shù)需要調(diào)用才能執(zhí)行 # 調(diào)用 lazy_sum()時(shí),每次調(diào)用都會(huì)返回一個(gè)新的函數(shù),即使傳入相同的參數(shù) f2 = lazy_sum(1,3,5,7,9) f1 == f2輸出結(jié)果
<function __main__.sum> 25 False分析:在函數(shù) lazy_sum 中又定義了函數(shù) sum,并且,內(nèi)部函數(shù) sum 可以引用外部函數(shù) lazy_sum 的參數(shù)和局部變量,當(dāng) lazy_sum 返回函數(shù) sum 時(shí),相關(guān)參數(shù)和變量都保存在返回的函數(shù)中,這種稱為“閉包( Closure) ”的程序結(jié)構(gòu)擁有極大的威力。
2、閉包
返回函數(shù)不要引用任何循環(huán)變量, 或者后續(xù)會(huì)發(fā)生變化的變量。
3、匿名函數(shù)
4、裝飾器
裝飾器”( Decorator):在代碼運(yùn)行期間動(dòng)態(tài)增加功能的方式。
5、偏函數(shù)
模塊
模塊:Python中一個(gè).py文件就是一個(gè)模塊(Module)
==》提高了代碼的可維護(hù)性;復(fù)用性;避免函數(shù)名和變量名沖突。
包(Package):按目錄來(lái)組織模塊的方法。例如:a.py(a模塊) 與 b.py(b模塊)與其他模塊沖突,則選擇一個(gè)頂層包名,例如mycompany,則 a 模塊變成 mycompany.a、b模塊變成 mycompany.b
==》每一個(gè)包目錄下面都會(huì)有一個(gè)__init__.py 的文件,這個(gè)文件是必須存在的,用于標(biāo)識(shí)包。
1、使用模塊
#!/usr/bin/env python3 # -*- coding:utf-8 -*-'a test module' ## 表示模塊的文檔注釋,任何模塊代碼的第一個(gè)字符串都被視為模塊的文檔注釋__author__ = '盛夏光年'import sysdef test():args = sys.argvif len(args)==1:print("Hello world!")elif len(args) == 2:print('Hello, %s!' % args[1])else:print('Too many arguments!')if __name__ == '__main__':test()2、作用域
- 正常的函數(shù)和變量名是公開的( public),可以被直接引用,比如: abc,x123, PI 等;
- 類似__xxx__這樣的變量是特殊變量,可以被直接引用,但是有特殊用途;
- 類似_xxx 和__xxx 這樣的函數(shù)或變量就是非公開的( private),不應(yīng)該被直接引用,比如_abc, __abc 等;
注意: Python 并沒有一種方法可以完全限制訪問 private 函數(shù)或變量
3、第三方庫(kù)
eg: Pillow、numpy、Jinja2
查看搜索目錄:
添加搜索目錄——方法1:
import sys sys.path.append('/Users/michael/my_py_scripts')==》這種方法是在運(yùn)行時(shí)修改,運(yùn)行結(jié)束后失效。
添加搜索目錄——方法2:
設(shè)置環(huán)境變量 PYTHONPATH
總結(jié)
以上是生活随笔為你收集整理的【Python】编程笔记5的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 金融贷款逾期的模型构建2——集成模型
- 下一篇: 【Python】编程笔记6