面向過程編程python
核心是過程二字,過程即解決問題的步驟,基於面向過程去設計程序就像是在設計一條工業流水線,是一種機械式的思惟方式linux
優勢:程序結構清晰能夠把複雜的問題簡單化,流程化
git
缺點:可擴展性差,一條流線只是用來解決一個問題
shell
應用場景:linux內核,git,httpd,shell腳本編程
練習:過濾目錄下文件內容包含error的文件數據結構
grep –rl ‘error’ /dirapp
使用os模塊walk方法:編程語言
os.walk會把目錄下的二級目錄和文件作成一個迭代器,屢次使用實現文件路徑的拼接ide
#grep -rl 'error' /dir/ import os def init(func): def wrapper(*args,**kwargs): g=func(*args,**kwargs) next(g) return g return wrapper #第一階段:找到全部文件的絕對路徑 @init def search(target): while True: filepath=yield g=os.walk(filepath) for pardir,_,files in g: for file in files: abspath=r'%s\%s' %(pardir,file) target.send(abspath) #第二階段:打開文件 @init def opener(target): while True: abspath=yield with open(abspath,'rb') as f: target.send((abspath,f)) #第三階段:循環讀出每一行內容 @init def cat(target): while True: abspath,f=yield #(abspath,f) for line in f: res=target.send((abspath,line)) if res:break #第四階段:過濾 @init def grep(pattern,target): tag=False while True: abspath,line=yield tag tag=False if pattern in line: target.send(abspath) tag=True #第五階段:打印該行屬於的文件名 @init def printer(): while True: abspath=yield print(abspath) g = search(opener(cat(grep('error'.encode('utf-8'), printer())))) g.send(r'D:\python location\python36\day05\a')
3、遞歸函數
遞歸調用:在調用一個函數的過程當中,直接或間接地調用了函數自己
Python中的遞歸在進行下一次遞歸時必需要保存狀態,效率低,沒有優化手段,因此對遞歸層級作了限制(其餘編程語言中有尾遞歸方式進行優化)
1. 必須有一個明確的結束條件
2. 每次進入更深一層遞歸時,問題規模相比上次遞歸都應有所減小
3. 遞歸效率不高,遞歸層次過多會致使棧溢出(在計算機中,函數調用是經過棧(stack)這種數據結構實現的,每當進入一個函數調用,棧就會加一層棧幀,每當函數返回,棧就會減一層棧幀。因爲棧的大小不是無限的,因此,遞歸調用的次數過多,會致使棧溢出)
尾遞歸優化:http://egon09.blog.51cto.com/9161406/1842475
#直接 def func(): print('from func') func() func() 輸出: from func from func … from funcTraceback (most recent call last): File "D:/python location/python36/day05/遞歸.py", line 8, in <module> func() [Previous line repeated 993 more times] RecursionError: maximum recursion depth exceeded while calling a Python object #調用Python對象時的最大遞歸深度超過了限制
若是遞歸層級過多,會報如上錯誤
#間接 def foo(): print('from foo') bar() def bar(): print('from bar') foo() foo() 輸出: RecursionError: maximum recursion depth exceeded while calling a Python object #調用Python對象時的最大遞歸深度超過了限制
修改遞歸層級限制(默認1000)
>>> import sys >>> sys.getrecursionlimit() 1000 >>> sys.setrecursionlimit(2000) >>> sys.getrecursionlimit() 2000
練習:
已知:
age(5)=age(4)+2
age(4)=age(3)+2
age(3)=age(2)+2
age(2)=age(1)+2
age(1)=18
首先作判斷:
age(n)=age(n-1)+2 #n>1
age(1)=18 #n=1
def age(n): if n == 1: return 18 return age(n-1)+2 print(age(5))
遞歸的執行分爲兩個階段:
1 遞推
2 回溯
遞歸和循環功能差很少,但在不知道循環次數時適合使用遞歸
練習:
取出列表中全部的元素
l =[1, 2, [3, [4, 5, 6, [7, 8, [9, 10, [11, 12, 13, [14,15,[16,[17,]],19]]]]]]] # def search(l): for item in l: if type(item) is list: search(item) else: print(item) search(l)
4、二分法
方法:
判斷一個數值是否存在於一個特別大的列表中,若是使用in方法會遍歷列表,佔內存過多,使用二分法每次會平分列表,佔用內存較少
練習:
#二分法 l = [1,2,5,7,10,31,44,47,56,99,102,130,240] def binary_search(l,num): print(l) #[10, 31] if len(l) > 1: mid_index=len(l)//2 #1 if num > l[mid_index]: #in the right l=l[mid_index:] #l=[31] binary_search(l,num) elif num < l[mid_index]: #in the left l=l[:mid_index] binary_search(l,num) else: print('find it') else: if l[0] == num: print('find it') else: print('not exist') return binary_search(l,32)