协程函数+面向过程+递归+二分法

回顾yield

yield
1.用在函数里,把函数的执行结果做成一个生成器,注意:是执行结果
2.与return功能类似,都可以返回值;return只能返回一次值,然后结束函数;yield可以返回多个值
3.yield会暂停函数,保存函数状态
def func(count):
 print('start')
 while True:
 yield count
 count +=1
 
func(10)
g=func(10)
print(g) #<generator object func at 0x000002341F69FDB0> 注意注意!!把函数的执行结果做成生成器generator,执行结果
next(g)#start next会触发生成器的执行
print(next(g)) #11
 
g.__iter__() #只有iter属性的是迭代对象
g.__next__()#iter和next都有的是迭代器,触发迭代器执行的是next,生成器本质上是迭代器
举例

协程函数讲解

本质上是 yield的表达式的应用
yield的表达式应用:
两个阶段:
1.初始化
next(g)
g.send(None)
2.传值
g.send('apple')
#一个什么都不做的装饰器模板
def init(func):
 def wrapper(*args,**kwargs):
 pass
 return wrapper
 
View Code
#自动初始化的装饰器
def init(func):
 def warpper(*args,**kwargs):
 g=func(*args,**kwargs)
 next(g)
 return g
 return warpper
@init
def eater(name):
 print('%s start eat' %name)
 food_list=[]
 while True:
 food=yield food_list
 food_list.append(food)
 print('%s start eat %s' %(name,food))
 
g=eater('alex')
print(g)
#初始化
#next(g)
#传值
print(g.send('apple'))
print(g.send('banana'))
举例

面向过程

核心是过程

介绍

核心是过程,过程即解决问题的步骤。基于面向过程的程序,就像是在设计一条工业流水线,是机械式的思维

优点:程序结构清晰,可以把复杂的问题简单化,流程化

缺点:可扩展性差,一条流水线只用来解决一个问题

应用场景:httpd  shell脚本 linux内核

举例详解

利用python实现以下命令的作用

grep  -rl 'error' /dir/  过滤出dir目录下所有带有‘error’的文件名字

先分析实现的过程(面向过程)

1.找出dir目录下所有的文件的绝对路径 os.walk()

2.打开文件

3. 每打开一个文件,循环过滤每一行

4.过滤‘error’关键字

5.打印带有‘error’行所属于的文件的绝对路径

基于分析步骤写代码

 目录结构如下:

每个文件的内容如下
a1.txt
ergreggr
error
error
a2.txt
fdhskdfvb
bdsskfhdsf
fdksfdsnf
ndskfuod
b1.txt
error
c1.txt
dhfdfh
errornfkd
dkjfhbv
djfdj
先介绍一下 os.walk()的用法
import os
g=os.walk(r'F:untitleda')
print(g)
print(next(g))
print(next(g))
print(next(g))
'''
打印结果
<generator object walk at 0x000002C158C3FE60>
('F:\untitled\a', ['b'], ['a1.txt', 'a2.txt']) 元组 列表 子目录 子文件
('F:\untitled\a\b', ['c'], ['b1.txt'])
('F:\untitled\a\b\c', [], ['c1.txt'])

'''
View Code

代码如下:

#装饰器
def init(func):
    def warpper(*args,**kwargs):
        g=func(*args,**kwargs)
        next(g)
        return g
    return  warpper
import os
#第一阶段:找到所有文件的绝对路径
@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
        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'F:untitleda')
View Code

 递归调用

 定义
在调用一个函数的过程中,直接或间接的调用了函数本身
递归效率低,需要在进入下一次递归时保留当前的状态,
解决方法是尾递归,即在函数的最后一步(而非最后一行)调用自己
但是python又没有尾递归,且对递归层级做了限制

1. 必须有一个明确的结束条件

2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少

3. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)
尾递归优化:http://egon09.blog.51cto.com/9161406/1842475

def func():
    print('sb')
    func()
func()
打印结果   递归在python里有次数限制,不会无限制递归的
RecursionError: maximum recursion depth exceeded while calling a Python object
View Code

递归必须有两个阶段:

递推

回溯

举例算年龄 每个人之间都相差两岁

def age(n):
    if n ==1:
        return 18
    return age(n-1)+2
print(age(6))
View Code

查看python解释器递归的限制数:

进入python解释器

>>> import sys
>>> sys.getrecursionlimit()
1000
>>> sys.setrecursionlimit(10000)
>>> sys.getrecursionlimit()
10000

二分法

二分法也是递归的应用

 举例如下:

l=[1,22,33,34,39,40,41,44,55,66,77,88,99,]
def binary_search(l,num):
    if len(l) > 1:
        mid_index=len(l)//2
        if num > l[mid_index]:
            l=l[mid_index:]
            binary_search(l,num)
        elif num < l[mid_index]:
            l=l[:mid_index]
            binary_search(l,num)
        else:
            print('find it',num)
    else:
        if l[0]==num:
            print('find it',num)
        else:
            print('not exits')
        return

binary_search(l,100)
View Code
原文地址:https://www.cnblogs.com/lazyball/p/7267998.html