python3-基礎7

協程函數python

面向過程編程shell

遞歸與二分法編程

內置函數   lambdaapp

模塊與包的使用函數

importspa

from ... import ...設計

 

經常使用模塊code

 

##################################協程

函數中只要有yield , 函數執行的結果就變成了一個生成器blog

他並不會立刻執行

生成器自己就是一個迭代器,使用next() 觸發函數的執行

yield功能

一、把函數的執行結果封裝好__iter__和__next__,獲得一個迭代器

二、與return功能相似,均可以返回值,但不一樣的是,return只能返回一次值,而yield能夠返回屢次值

三、函數暫停與再繼續運行的狀態是有yield保存

 1 #
 2 def func(count):
 3     print('start')
 4     while True:
 5         yield count
 6         count+=1
 7 
 8 g=func(10)
 9 # print(g)
10 print(next(g))
11 
12 print(next(g))

yield的表達式形式的應用

吃飯的過程,三種方法:

 1 #yield的表達式形式的應用
 2 #吃飯的過程
 3 ##方法一:
 4 def eater(name):
 5     print('%s 說:我要開始吃東西啦!' %name)
 6     food_list = [] #定義一個菜單空列表
 7     while True:
 8 #         food=yield   #yield 沒有返回值,後面須要給yield賦值,只要函數中有yield關鍵字,函數執行的結果就是一個生成器
 9         food=yield food_list #返回值 菜單列表
10         food_list.append(food)  #往列表中添加值
11         print('%s eat %s !' %(name,food))
12 
13 alex_g=eater('alex') #函數要執行下,才能獲得一個生成器
14 # print(alex_g)  #是個生成器 <generator object eater at 0x0000000006B522B0>
15 
16 # print(next(alex_g))   #執行結果  None
17 # print('==============>')
18 # print(next(alex_g))   #執行結果 alex eat None  , food沒有接收到值 ,因此每次都要給food傳一個值,經過yield取值賦值給food
19 # print('==============>')
20 # print(next(alex_g))
21 #第一階段 初始化  next()  生成器剛開始的時候,必須給一個None值
22 next(alex_g)  #保證在初始的位置,簡單的觸發生成器的執行,保證函數停在yield位置  等同於 alex_g.send(None)
23 print('==========>')
24 
25 #第二階段 給yield傳值  經過alex_g.send() 發送值
26 alex_g.send('包子')  #發送值  先給當前暫停位置的yield傳值 , 執行結果爲:  alex eat 包子
27 #繼續往下執行,直到再次碰到yield,而後暫停,而且把yield後的返回值當作本次調用的返回值
28 # alex_g.send('八寶粥')  #發送值
29 print(alex_g.send('八寶粥'))
30 print(alex_g.send('煎餃'))
 1 ##方法二:
 2 ##修改第二階段
 3 
 4 def eater(name):
 5     print('%s 說:我要開始吃東西啦!' %name)
 6     food_list = [] #定義一個菜單空列表
 7     while True:
 8         food=yield food_list #返回值 菜單列表
 9         food_list.append(food)  #往列表中添加值
10         print('%s eat %s !' %(name,food))
11 
12 alex_g=eater('alex') #函數要執行下,才能獲得一個生成器
13 
14 next(alex_g)  
15 print('==========>')
16 
17 ##第二階段傳值的功能寫成一個交互函數
18 
19 def producer():
20     alex_g=eater('alex')
21     #第一階段:初始化
22     next(alex_g)
23     #第二階段:給yield傳值
24     while True:
25         food=input('>>: ').strip()
26         if not food:continue
27         print(alex_g.send(food))
28 
29 
30 producer()
31 ##############################
 1 ##方法三:
 2 
 3 #不容易記得初始化
 4 #用裝飾器解決初始化問題
 5 ####裝飾器基本形式
 6 '''
 7 def init(func):
 8     def wrapper(*args, **kwargs):
 9         pass
10     return wrapper
11 '''
12 ##先寫個什麼都沒幹的裝飾器
13 '''
14 def init(func):
15     def wrapper(*args, **kwargs):
16         g = func(*args, **kwargs)
17         return g
18     return wrapper
19 '''
20 #完成調用初始化工做
21 def init(func):
22     def wrapper(*args, **kwargs):
23         g = func(*args, **kwargs)
24         next(g) #調用next()初始化
25         return g
26     return wrapper
27 @init   #將裝飾器加在目錄函數上
28 def eater(name):
29     print('%s 說:我要開始吃東西啦!' %name)
30     food_list = [] #定義一個菜單空列表
31     while True:
32 #         food=yield   #yield 沒有返回值,後面須要給yield賦值,只要函數中有yield關鍵字,函數執行的結果就是一個生成器
33         food=yield food_list #返回值 菜單列表
34         food_list.append(food)  #往列表中添加值
35         print('%s eat %s !' %(name,food))
36 
37 alex_g=eater('alex')
38 alex_g.send('包子')  
39 print(alex_g.send('八寶粥'))
40 print(alex_g.send('煎餃'))

 面向過程

 面向過程:核心是過程二字,明確的區分幾個階段,

基於面向過程去設計程序就像是在設計一條工業流水線,是一種機械式的思惟方式

過程即解決問題的步驟
寫程序要先設計

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

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

應用場景:Linux內核, Git, httpd, shell腳本

 

 1 ##遍歷目錄下的全部文件
 2 #三種方式
 3 #1、普通方式:
 4 import os   #導入os模塊,os下面有個walk模塊,他是個生成器
 5 import time
 6 
 7 #第一階段:找到全部文件的絕對路徑
 8 #使用os.walk()的方法,將walk生成的元組裏的元素拼接成絕對路徑
 9 def search(filepath):
10     g=os.walk(filepath)
11     for pardir,_,files in g:
12         for file in files:
13             abspath = r'%s\%s' %(pardir,file)
14             print(abspath)
15 fp = input('請輸入目錄絕對路徑:')            
16 search(r'%s'  % (fp))
17 time.sleep(10)
18 
19 ##2、裝飾器方式,手動初始化裝飾器
20 import os   #導入os模塊,os下面有個walk模塊,他是個生成器
21 import time
22 
23 #第一階段:找到全部文件的絕對路徑
24 #使用os.walk()的方法,將walk生成的元組裏的元素拼接成絕對路徑
25 def search():
26     while True:
27         filepath = yield
28         g=os.walk(filepath)
29         for pardir,_,files in g:
30             for file in files:
31                 abspath = r'%s\%s' %(pardir,file)
32                 print(abspath)
33           
34 fp = input('請輸入目錄絕對路徑:')            
35 g = search()  #使用裝飾器,要先初始化
36 next(g) #初始化
37 
38 g.send(r'%s'  % (fp))
39 time.sleep(10)
40 
41 ##3、自動初始化裝飾器
42 import os   #導入os模塊,os下面有個walk模塊,他是個生成器
43 import time
44 
45 def init(func):   #解決初始化問題
46     def wrapper(*args,**kwargs):
47         g=func(*args,**kwargs)
48         next(g)
49         return g
50     return wrapper
51 @init
52 #第一階段:找到全部文件的絕對路徑
53 #使用os.walk()的方法,將walk生成的元組裏的元素拼接成絕對路徑
54 def search():
55     while True:
56         filepath = yield
57         g=os.walk(filepath)
58         for pardir,_,files in g:
59             for file in files:
60                 abspath = r'%s\%s' %(pardir,file)
61                 print(abspath)
62 # g = search('Null')
63 # next(g)            
64 fp = input('請輸入目錄絕對路徑:')            
65 
66 g = search()  #使用裝飾器,要先初始化
67 # next(g) #初始化
68 g.send(r'%s'  % (fp))
69 time.sleep(10)

 

 1 #面向過程:核心是過程二字
 2 #過程即解決問題的步驟
 3 #寫程序要先設計
 4 
 5 
 6 #grep -rl 'error' /dir/   
 7 #-r是遞歸着找,-l 是系列出文件名 ,找出目錄下的全部文件,打開文件,找出有 error 的關鍵字,列出包含error的行的文件名
 8 #思路:找出全部文件的絕對路徑、打開文件、循環逐行讀取每行文件內容、判斷error是否在文件裏(過濾)、打印改行屬於的文件名
 9 import os   #導入os模塊,os下面有個walk模塊,他是個生成器
10 def init(func):  #寫一個裝飾器,完成調用初始化工做
11     def wrapper(*args,**kwargs):
12         g=func(*args,**kwargs)
13         next(g)
14         return g
15     return wrapper
16 
17 #第一階段:找到全部文件的絕對路徑
18 #使用os.walk()的方法,將walk生成的元組裏的元素拼接成絕對路徑
19 def search(filepath):
20     g=os.walk(filepath)
21     for parddir,_,file in g:
22         for file in files:
23             abspath = r'%S\%s' %(pardir,file)
24             print(abspath)
25 search(r'F:\study\18期')            
26 @init
27 def search(target):   #定義一個找路徑的功能
28     while True:
29         filepath=yield
30         g=os.walk(filepath)  #生成器,使用next()方法,能夠讀取該文件的路徑、目錄、文件名,並將其爲元素組成一個元組。
31         for pardir,_,files in g:
32             for file in files:
33                 abspath=r'%s\%s' %(pardir,file)
34                 target.send(abspath)
35 # search(r'C:\Users\Administrator\PycharmProjects\python123\day5\aaa')
36 # g=search()
37 # g.send(r'C:\Python27')
38 
39 #第二階段:打開文件
40 @init
41 def opener(target):
42     while True:
43         abspath=yield
44         with open(abspath,'rb') as f:
45             target.send((abspath,f))
46 
47 
48 
49 
50 #第三階段:循環讀出每一行內容
51 @init
52 def cat(target):
53     while True:
54         abspath,f=yield #(abspath,f)
55         for line in f:
56             res=target.send((abspath,line))
57             if res:break
58 
59 
60 
61 #第四階段:過濾
62 @init
63 def grep(pattern,target):
64     tag=False
65     while True:
66         abspath,line=yield tag
67         tag=False
68         if pattern in line:
69             target.send(abspath)
70             tag=True
71 
72 
73 #第五階段:打印該行屬於的文件名
74 @init
75 def printer():
76     while True:
77         abspath=yield
78         print(abspath)
79 
80 g = search(opener(cat(grep('os'.encode('utf-8'), printer()))))
81 # g.send(r'C:\Users\Administrator\PycharmProjects\python123\day5\aaa')
82 
83 g.send(r'C:\Users\Administrator\PycharmProjects\python234')
84 #a1.txt,a2.txt,b1.txt

 

#遞歸
'''
遞歸調用:再調用一個函數的過程當中,直接或間接的調用了函數自己
python中遞歸的效率不高
記錄下一次遞歸,保留上一次遞歸的狀態,python對遞歸層級作了限制,默認1000層
程序中必須有個明確的結束條件

 1 直接調用:
 2 #直接
 3 # def func():
 4 # print('from func')
 5 # func()
 6 #
 7 # func() #直接
 8 
 9 #間接
10 # def foo():
11 # print('from foo')
12 # bar()
13 #
14 # def bar():
15 # print('from bar')
16 # foo()
17 #
18 # foo() #間接調用

 

迭代 每一次更新都是上一次更新的結果
遞歸 直接或間接的調用了函數自己

遞歸包含兩個階段
遞推:一層層的往下
回溯:一層層的回溯

何時用遞歸:
遞歸就是個循環的過程,遞歸能夠作的,循環能夠也能夠作,只是麻煩點
循環是要明確的知道循環多少次
遞歸不須要

 1 2 #取出列表中的全部元素
 3 #若果使用循環,無法判斷循環多少次,這裏用遞歸來取值
 4 
 5 list1 =[1, 2, [3, [4, 5, 6, [7, 8, [9, 10, [11, 12, 13, [14, 15,[16,[17,]],19]]]]]]] #有不少層
 6 
 7 
 8 def search(l): #定義功能,給一個l參數
 9 for i in l: #循環列表l中的元素
10 if type(i) is list: #判斷若是元素是個列表
11 search(i) #重複該功能,繼續查找元素
12 else:
13 print(i) #打印該元素
14 
15 search(list1) #調用該功能
16 #

 二分法

##二分法(把一組元素一半一半的一直分下去)
#在下列列表中,搜索某個值是否存在,若存在請提示"find it!"  ,  除了in,如何遍歷,使用二分法遍歷
#若搜索的是不存在的,則返回「no exist!」

l = [1,2,5,7,10,31,44,47,56,99,102,130,240,332,346.480,520,527,572,666,668,888,999]  #從小到大排列(假設列表有不少值), 

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,888)

####結果
[1, 2, 5, 7, 10, 31, 44, 47, 56, 99, 102, 130, 240, 332, 346.48, 520, 527, 572, 666, 668, 888, 999]
[1, 2, 5, 7, 10, 31, 44, 47, 56, 99, 102]
[1, 2, 5, 7, 10]
[5, 7, 10]
[7, 10]
[7]
not exist!
相關文章
相關標籤/搜索