Python学习之旅-18

来源:互联网 发布:幼儿看图学英语软件 编辑:程序博客网 时间:2024/06/06 21:43

生成器、三元表达式、列表生成式、生成器表达式

生成器

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

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

yield的功能:
  1.与return类似,都可以返回值,但不一样的地方在于可以有多个yield,每个yield能够返回一次值,而return只能返回一次值就结束了
  2.为函数封装好了iternext方法,把函数的执行结果做成了迭代器
  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------>1second----->2third----->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------>1second----->2third----->3fouth----->

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

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------>1first------>1first------>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 countdown54321stop countdown

生成器模拟linux命令:tail -f a.txt |grep ‘error’ |grep ‘404’
当在a.txt文件中输入字符串,如果包含error并且包含404,那么将打印出该行,其他不打印

import timedef 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 lineg1=tail('a.txt')g2=grep(g1,'error')g3=grep(g2,'404')for i in g3:    print(i)

三元表达式

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

x=2y=3if 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 yprint(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>0123
原创粉丝点击