python3-基础7

协程函数

面向过程编程

递归与二分法

内置函数   lambda

模块与包的使用

import

from ... import ...

常用模块

##################################

函数中只要有yield , 函数执行的结果就变成了一个生成器

他并不会马上执行

生成器本身就是一个迭代器,使用next() 触发函数的执行

yield功能

1、把函数的执行结果封装好__iter__和__next__,得到一个迭代器

2、与return功能类似,都可以返回值,但不同的是,return只能返回一次值,而yield可以返回多次值

3、函数暂停与再继续运行的状态是有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 #一、普通方式:
 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 ##二、装饰器方式,手动初始化装饰器
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 ##三、自动初始化装饰器
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:study18期')            
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:UsersAdministratorPycharmProjectspython123day5aaa')
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:UsersAdministratorPycharmProjectspython123day5aaa')
82 
83 g.send(r'C:UsersAdministratorPycharmProjectspython234')
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!
原文地址:https://www.cnblogs.com/Albert-w/p/10711173.html