zoukankan      html  css  js  c++  java
  • 协程函数+面向过程+递归+二分法

    回顾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
  • 相关阅读:
    Awesome Adb——一份超全超详细的 ADB 用法大全
    adb devices unauthorized的解决办法
    Vim用法AAAAA
    Security arrangements for extended USB protocol stack of a USB host system
    六 Python基础 字符串和编码
    四 Python基础
    三 Python解释器
    二安装Python
    Python教程(一)Python简介
    Python基本语法[二]
  • 原文地址:https://www.cnblogs.com/lazyball/p/7267998.html
Copyright © 2011-2022 走看看