python基礎---面向過程編程

                                                    面向過程編程python


       核心是過程二字,過程即解決問題的步驟,基於面向過程去設計程序就像是在設計一條工業流水線,是一種機械式的思惟方式linux


優勢:程序結構清晰能夠把複雜的問題簡單化,流程化

git

缺點:可擴展性差,一條流線只是用來解決一個問題

shell

應用場景:linux內核,githttpdshell腳本編程


練習:過濾目錄下文件內容包含error的文件數據結構

grep –rl ‘error’ /dirapp

使用os模塊walk方法:編程語言

os.walk會把目錄下的二級目錄和文件作成一個迭代器,屢次使用實現文件路徑的拼接ide

wKiom1mCAsCj8FMCAAFWif5hlXI802.png

#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 回溯

wKioL1mCA-azEeaZAABbE7nPVcM799.png



遞歸和循環功能差很少,但在不知道循環次數時適合使用遞歸


練習:

取出列表中全部的元素

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)
相關文章
相關標籤/搜索