• Python基础----生成器、三元表达式、列表生成式、生成器表达式


    生成器

    生成器函数:函数体内包含有yield关键字,该函数执行的结果是生成器,生成器在本质上就是迭代器。

    复制代码
    def foo():
        print('first------>')
        yield 1
        print('second----->')
        yield 2
        print('third----->')
        yield 3
        print('fouth----->')
    g=foo()
    from collections import Iterator
    print(isinstance(g,Iterator))
    print(g)
    复制代码

    yield的功能:

      1.与return类似,都可以返回值,但不一样的地方在于可以有多个yield,每个yield能够返回一次值,而return只能返回一次值就结束了

      2.为函数封装好了__iter__和__next__方法,把函数的执行结果做成了迭代器

      3.遵循迭代器的取值方式obj.__next__(),触发的函数的执行,函数暂停与再继续的状态都是由yield保存的

    生成器的使用

    复制代码
    def foo():
        print('first------>')
        yield 1
        print('second----->')
        yield 2
        print('third----->')
        yield 3
        print('fouth----->')
    g=foo()
    print(g.__next__())
    print(g.__next__())
    print(g.__next__())
    # print(g.__next__())
    
    输出结果
    first------>
    1
    second----->
    2
    third----->
    3
    复制代码

    第一次g.__next__()在函数体的第一个yield结束后暂停,并执行前面的指令

    第二次g.__next__()在函数体的第二个yield结束后暂停,并执行前面的指令

    第三次g.__next__()在函数体的第三个yield结束后暂停,并执行前面的指令

    如果来第四次g.__next__()方法,将抛出StopIteration提示错误

    for循环调用:for会自动处理StopIteration,当遇到StopIteration自动停止

    for i in g: #obj=g.__iter__()   #obj.__next__()
        print(i)

    输出结果

    复制代码
    first------>
    1
    second----->
    2
    third----->
    3
    fouth----->
    复制代码

    如果生成器函数不赋值变量,那么每次执行都是全新的生成器函数,并没有迭代的效果,如下:

    复制代码
    def foo():
        print('first------>')
        yield 1
        print('second----->')
        yield 2
        print('third----->')
        yield 3
        print('fouth----->')
    print(foo().__next__())
    print(foo().__next__())
    print(foo().__next__())
    
    输出结果
    first------>
    1
    first------>
    1
    first------>
    1
    复制代码

    使用print测试foo函数,会发现,同一时间输出的foo函数,内存地址并不同

    print(foo(),foo(),foo())
    
    输出结果:
    <generator object foo at 0x00000251392F1E60> <generator object foo at 0x00000251392F1DB0> <generator object foo at 0x00000251392F1EB8>

    生成器示例:一个yield返回多个值

    复制代码
    def countdown(n):
        print('starting countdown')
    
        while n > 0:
            yield n
            n-=1
        print('stop countdown')
    g=countdown(5)
    for i in g:
        print(i)
    
    输出结果
    starting countdown
    5
    4
    3
    2
    1
    stop countdown
    复制代码

    生成器模拟linux命令:tail -f a.txt |grep 'error' |grep '404'

    当在a.txt文件中输入字符串,如果包含error并且包含404,那么将打印出该行,其他不打印

    复制代码
    import time
    def tail(filepath,encoding='utf-8'):
        with open(filepath,encoding=encoding) as f:
            f.seek(0,2)
            while True:
                # f.seek(0, 2) #不行
                line=f.readline()
                if line:
                    # print(line,end='')
                    yield line
                else:
                    time.sleep(0.5)
    
    def grep(lines,pattern):
        for line in lines:
            if pattern in line:
                # print(line)
                yield line
    
    g1=tail('a.txt')
    g2=grep(g1,'error')
    g3=grep(g2,'404')
    for i in g3:
        print(i)
    复制代码

    三元表达式

    简化代码量:比较两个数的大小,可以用以下if语句完成

    x=2
    y=3
    if x > y:
        print(x)
    else:
        print(y)

    使用三元表达式:可以简化成一行解决

    res='x' if x > y else 'y'
    print(res)

    三元表达式即 'x' if x > y else 'y'

    当条件为真,那么输出条件左边的值,当条件为假则输出右边的值

    示例:

    复制代码
    def max2(x,y):
        # if x > y:
        #     return x
        # else:
        #     return y
        return x if x > y else y
    print(max2(1,2))
    复制代码

    列表生成式

    简化生成列表的代码量

    如:将s='hello'的字符串转化成大写,并将每一个字符转化成列表元素,即['H','E','L','L','O']

    普通循环代码:

    s='hello'
    l=[]
    for i in s:
        res=i.upper()
        l.append(res)
    print(l)

    列表解析代码:

    s='hello'
    res=[i.upper() for i in s]
    print(res)

    使用列表解析能够简化简单的代码生成

    列表生成式说明:

    示例:

    l=[1,31,73,84,57,22]
    print([i for i in l if i > 50])    #l列表中大于50的元素生成一个新列表
    print([i for i in l if i < 50])    #l列表中小于50的元素生成一个新列表
    print([i for i in l if i > 20 and i < 50]) #l列表中大于20小于50的元素生成一个新列表

    生成器表达式

    类似于列表生成式,只不过将中括号换成小括号,每次执行next将输出一个元素,占用内存小,每次只占用一个元素的内存空间

    复制代码
    g=(i for i in range(1000))
    print(g)    #生成器
    print(next(g))    #每次执行next(g)即可输出一个元素
    print(next(g)) 
    print(next(g)) 
    print(next(g)) 
    
    输出结果
    <generator object <genexpr> at 0x00000205FFE91E60>
    0
    1
    2
    3
    复制代码
  • 相关阅读:
    Laravel $request添加数据或数据修改
    PHP 生成随机字符串
    MySQL 的日期类型有5个,分别是: date、time、year、datetime、timestamp。
    Windows10系统PHP开发环境配置
    yii 分页查询
    win10系统 安装好composer后 cmd 命令行下输入composer提示不是内部或外部的命令,也不是可执行的程序或批处理文件
    MySQL锁机制&&PHP锁机制,应用在哪些场景中呢?
    linux 自总结常用命令(centos系统)
    HTTP和HTTPS有什么区别? 什么是SSL证书?使用ssl证书优势?
    怎么在vi和vim上查找字符串
  • 原文地址:https://www.cnblogs.com/chenqizhou/p/7117439.html
Copyright © 2020-2023  润新知