zoukankan      html  css  js  c++  java
  • python基础之协程函数、列表表达式、生成器表达式

    一、协程函数

    协程函数的定义?
    如果在一个函数内部yield的使用方式是表达式形式的话,如x=yield,那么该函数称为协程函数

    协程函数补充:

    def init(func):
        def wrapper(*args,**kwargs):
            res=func(*args,**kwargs)
            next(res)
            return res
        return wrapper
    
    @init #eater=init(eater)
    def eater(name):
        print('%s start to eat' % name)
        food_list=[]
        while True:
            food = yield food_list
            print('%s eat %s' % (name, food))
            food_list.append(food)
    
    e = eater('luchuan') #wrapper('luchuan')
    # print(e)
    # next(e) #e.send(None)
    
    print(e.send('123'))
    print(e.send('123'))
    print(e.send('123'))
    print(e.send('123'))
    print(e.send('123'))
    

    协程函数的应用?

    递归文件夹及子文件夹中的文件,把有'python'参数的文件绝对路径打印出来:

    #grep -rl 'python' C:luchuan

    import os,time
    def init(func):  #装饰器next()
        def wrapper(*args,**kwargs):
            res=func(*args,**kwargs)
            next(res)
            return res
        return wrapper
    
    @init
    def search(target):
        '找到文件的绝对路径'
        while True:
            dir_name=yield
            print('车间search开始生产产品:文件的绝对路径')
            time.sleep(0.2)
            g=os.walk(dir_name)
            for i in g:
                for j in i[-1]:
                    file_path = '%s\%s' % (i[0],j)
                    target.send(file_path)
    
    @init
    def opener(target):
        '打开文件,获取文件句柄'
        while True:
            file_path=yield
            print('车间opener开始生产产品:文件句柄')
            time.sleep(0.2)
            with open(file_path) as f:
                target.send((file_path,f))
    
    @init
    def cat(target):
        '读取文件内容'
        while True:
            file_path,f=yield
            print('车间cat开始生产产品:文件的一行内容')
            time.sleep(0.2)
            for line in f:
                target.send((file_path,line))
    
    @init
    def grep(pattern,target):
        while True:
            file_path,line=yield
            print('车间grep开始生产产品:包含python这一行内容的文件路径')
            time.sleep(0.2)
            if pattern in line:
                target.send(file_path)
    
    @init
    def printer():
        while True:
            file_path=yield
            print('车间printer开始生产产品:得到最终的产品')
            time.sleep(0.2)
            print(file_path)
    
    g=search(opener(cat(grep('python',printer()))))
    g.send("C:\luchuan")
    # g.send("C:\lulu") #也可以传其他路径

    os.walk()方法用于通过在目录树中游走输出在目录中的文件名,向上或者向下。
    在Unix,Windows中有效。

    import os
    
    g=os.walk('C:\luchuan') #遍历所有luchuan路径下的文件绝对路径
    for i in g:
        # print(i)
        for j in i[-1]:
            file_path='%s\%s' %(i[0],j)
            print(file_path)
    

    二、面向过程编程

    以上协程函数应用就是面向过程编程。

    面向过程的编程思想:流水线式的编程思想,在设计程序时,需要把整个流程设计出来。
    优点:

    1. 体系结构更加清晰
    2. 简化程序的复杂度

    缺点:

    1. 可扩展性极其的差,所以说面向过程的应用场景是:不需要经常变化的软件,如:linux内核,httpd,git等软件。

    三、列表解析

    声明式编程:列表解析、生成器表达式都是声明式编程,就跟声明变量一样。

    三元表达式:
    三元运算时if-else语句的快捷操作,也被称为条件运算。可以让你的代码更加紧凑,更加美观。

    [on_true] if [expression] else [on_false]

    x, y = 50, 25
    small = x if x < y else y
    

    列表解析初识:

    egg_list=[]
    
    for i in range(100):  #for循环表示
        egg_list.append('egg%s' %i)
    print(egg_list)
    
    l=[ 'egg%s' %i for i in range(100) ]  #列表表达式表示
    print(l)
    

    复杂的列表解析:

    #应用1:
    l=[1,2,3,4]
    s='hello'
    
    l1=[]
    for num in l:
        for s1 in s:
            t=(num,s1)
            l1.append(t)
    print(l1)
    
    l1=[ (num,s1) for num in l if num > 2 for s1 in s ]
    print(l1)
    
    #应用2:
    import os
    g=os.walk('C:\luchuan')
    file_path_list=[]
    
    for i in g:
        # print(i)
        for j in i[-1]:
            file_path_list.append('%s\%s' %(i[0],j))
    print(file_path_list)
    
    g=os.walk('C:\luchuan')
    l1=['%s\%s' %(i[0],j) for i in g for j in i[-1]]
    print(l1)
    

    四、生成器表达式

    把列表解析的[]换成()得到的就是生成器表达式,语法和列表解析一样。

    生成器表达式初识:

    l=['egg%s' %i for i in range(100)]
    print(l)
    
    g=l=('egg%s' %i for i in range(1000000000000000000000))
    # print(g)
    # print(next(g))
    # print(next(g))
    for i in g:
        print(i)

    生成器表达式扩展:

    # 应用1:
    f=open('a.txt')
    l=[]
    for line in f:
        line=line.strip()
        l.append(line)
    print(l)
    
    f.seek(0)
    l1=[line.strip() for line in f]
    print(l1)
    
    f.seek(0)
    g=(line.strip() for line in f)
    print(g)
    print(next(g))
    
    f=open('a.txt')
    g=(line.strip() for line in f)
    l=list(g)
    print(l)
    
    # 应用2:
    nums_g = (i for i in range(3))
    print(sum(nums_g))
    
    print(sum([1,2,3,4]))
    
    # 应用3:
    money_l=[]
    with open('b.txt') as f:
        for line in f:
            goods=line.split()
            res=float(goods[-1])*float(goods[-2])
            money_l.append(res)
    print(money_l)
    
    f=open('b.txt')  # 推荐使用这种方式写代码
    g=(float(line.split()[-1])*float(line.split()[-2]) for line in f)
    print(sum(g))
    
    with open('b.txt') as f:  # 不建议使用这种方式,代码不易观察
        print(sum((float(line.split()[-1])*float(line.split()[-2]) for line in f)))
    
    # 应用4:
    res=[]
    with open('b.txt') as f:
        for line in f:
            # print(line)
            l=line.split()
            # print(l)
            d={}
            d['name']=l[0]
            d['price']=l[1]
            d['count']=l[2]
            res.append(d)
    print(res)
    
    #取出单价>10000
    with open('b.txt') as f:
        res=(line.split() for line in f)
        # print(res)
        dic_g=({'name':i[0],'price':i[1],'count':i[2]} for i in res if float(i[1]) > 10000)
        # print(dic_g)
        print(list(dic_g))
                     asdfasdfasdfasdfasdf
         123123123123
         123123123123
         123123123123
         123123123123
         123123123123
         123123123123
         123123123123
         123123123123
         123123123123
         123123123123
         123123123123
         123123123123
         123123123123
         123123123123
         123123123123
         123123123123
         123123123123
         123123123123
         123123123123
    123123123123
    
    asdfasdfasdfasdf
    文件a.txt
    apple 10 3
    banana 5 10
    tesla 1000000.3 1
    lenovo 10000 3
    文件b.txt

    总结:

    总结:
    1、把列表解析的[]换成()得到的就是生成器表达式
    2、列表解析与生成器表达式都是一种便利的编程方式,只不过生成器表达式更节省内存
    3、python不但使用迭代器协议,让for循环变得更加通用。大部分内置函数,也是使用迭代器协议访问对象的。例如,sum函数是Python的内置函数,该函数使用迭代器协议访问对象,而生成器实现了迭代器协议,所以,我们可以直接这样计算一系列值的和:

    num=sum(x ** 2 for x in range(4))

    而不用多此一举的先构造一个列表:

    num=sum([x ** 2 for x in range(4)])

    练习题:

    习题一:

    有两个列表,分别存放来老男孩报名学习linux和python课程的学生名字
    linux=['钢弹','小壁虎','小虎比','alex','wupeiqi','yuanhao']
    python=['dragon','钢弹','zhejiangF4','小虎比']

    问题一:得出既报名linux又报名python的学生列表

    L=[]
    for i in linux:
        for j in python:
            if i == j:
                L.append(i)
    print(L)
    
    lp=[i for i in linux for j in python if i==j ]
    print(lp)

    问题二:得出只报名linux,而没有报名python的学生列表

    L=[]
    for i in linux:
        if i not in python:
            L.append(i)
    print(L)
    
    lp=[i for i in linux if i not in python ]
    print(lp)

    问题三:得出只报名python,而没有报名linux的学生列表

    L = []
    for j in python:
        if j not in linux:
            L.append(j)
    print(L)
    
    lp=[ j for j in python if j not in linux ]
    print(lp)

    习题二:

    shares={
    'IBM':36.6,
    'lenovo':27.3,
    'huawei':40.3,
    'oldboy':3.2,
    'ocean':20.1
    }

    问题一:得出股票价格大于30的股票名字列表

    L=[]
    for i in shares:
        print(i,shares[i])
        if shares[i] > 30:
            L.append(i)
    print(L)
    
    lp = [i for i in shares if shares[i] > 30]
    print(lp)
    

    问题二:求出所有股票的总价格

    L=[]
    for i in shares:
        L.append(shares[i])
    print(sum(L))
    
    num=sum(shares[i] for i in shares)
    print(num)

    习题三:

    l=[10,2,3,4,5,6,7]

    得到一个新列表l1,新列表中每个元素是l中对应每个元素值的平方

    l1=[]
    for i in l:
        l1.append(i**2)
    print(l1)
    
    lp=[i**2 for i in l]
    print(lp)
    

    过滤出l1中大于40的值,然后求和

    l1=[]
    for i in l:
        if i**2 > 40:
            l1.append(i**2)
    print(sum(l1))
    
    lp=sum(i**2 for i in l if i**2 > 40)
    print(lp)
    

      

  • 相关阅读:
    设计模式之装饰模式(Decorator)
    原型模式(浅克隆和深克隆)
    (原创)C#初级教程学习笔记001-学习路线
    (原创)C#零基础学习笔记012-多线程开发
    (原创)C#零基础学习笔记011-事件和委托
    (原创)C#零基础学习笔记010-数据流技术
    (原创)C#零基础学习笔记009-异常处理
    (原创)C#零基础学习笔记008-C#集合处理
    (原创)C#零基础学习笔记007-面向对象的特性
    (原创)C#零基础学习笔记006-面向对象编程基础
  • 原文地址:https://www.cnblogs.com/luchuangao/p/6699483.html
Copyright © 2011-2022 走看看