生成器

生成器函数:函数体内包含有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

python基础之生成器、三元表达式、列表生成式、生成器表达式的更多相关文章

  1. python基础之协程,列表生成式,生成器表达式

    三元表达式 #三元表达式 name = 'alex' name = 'egon' res='SB' if name == 'alex'else 'shuai' print(res)#输出:shuai ...

  2. python基础--切片、迭代、列表生成式

    原文地址:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/00143175684 ...

  3. python高级特性:切片/迭代/列表生成式/生成器

    廖雪峰老师的教程上学来的,地址:python高级特性 下面以几个具体示例演示用法: 一.切片 1.1 利用切片实现trim def trim(s): while s[:1] == " &qu ...

  4. python协程函数应用 列表生成式 生成器表达式

    协程函数应用 列表生成式 生成器表达式   一.知识点整理: 1.可迭代的:对象下有_iter_方法的都是可迭代的对象 迭代器:对象._iter_()得到的结果就是迭代器 迭代器的特性: 迭代器._n ...

  5. Python 函数递归-三元表达式-列表生成式-字典生成式-匿名函数-内置函数

    上节课复习: 1. 无参装饰器 def 装饰器名字(func): def wrapper(*args,**kwargs): res = func(*args,**kwargs) return res ...

  6. 第五篇:python基础之循环结构以及列表

    python基础之循环结构以及列表   python基础之编译器选择,循环结构,列表 本节内容 python IDE的选择 字符串的格式化输出 数据类型 循环结构 列表 简单购物车的编写 1.pyth ...

  7. Py修行路 python基础 (十二) 协程函数应用 列表生成式 生成器表达式

    一.知识点整理: 1.可迭代的:对象下有_iter_方法的都是可迭代的对象 迭代器:对象._iter_()得到的结果就是迭代器 迭代器的特性: 迭代器._next_() 取下一个值 优点: 1.提供了 ...

  8. python基础--递归、三元表达式、列表(字典)生成式、匿名函数、常用的内置函数

    函数的递归:函数在调用阶段直接或者间接的又调用自身 递归的两个阶段: 1.回溯:就是一次次重复的过程,这个重复的过程必须建立在每一次重复问题的复杂度都是应该下降的,直接有一个最终的结束条件(这个结束条 ...

  9. python递归-三元表达式-列表生成式-字典生成式-匿名函数-部分内置函数-04

    递归 递归: # 函数在调用阶段直接或间接地又调用了自身 应用场景: # 将列表中的数字依次打印出来(循环的层数是你必须要考虑的点)   -->  l = [1, [2, [3, [4, [5, ...

  10. Python 非空即真、列表生成式、三元表达式 day3

    一.非空即真: Python程序语言指定任何非0和非空(null)值为true,0 或者 null为false 布尔型,False表示False,其他为True 整数和浮点数,0表示False,其他为 ...

随机推荐

  1. <Android 基础(六)> ActionBar

    介绍 Action Bar是一种新増的导航栏功能,在Android 3.0之后加入到系统的API当中,它标识了用户当前操作界面的位置,并提供了额外的用户动作.界面导航等功能.使用ActionBar的好 ...

  2. unity工具介绍

    MemoryProfiler内存分析工具 行为树 behaviac github 场景动画编辑器 Snapdragon Profiler性能分析工具 VTune性能分析器 protobuf数据交换格式 ...

  3. SQL SERVER 错误代码 0x534

    解决办法就是修改一下登陆名: ALTER LOGIN [G-PC\zqwang]   WITH NAME=[新的机器名\zqwang]; 然后查询一下 Service Broker 队列, 里面已经有 ...

  4. html:<link> 标签中的 media 属性

    HTML <link> 标签的 media 属性 定义和用法 media 属性规定被链接文档将显示在什么设备上. media 属性用于为不同的媒介类型规定不同的样式. media属性值 ( ...

  5. Gym 100090D Insomnia

    从 n 变到 1,有多少种方案? 打表记忆化. #include <bits/stdc++.h> using namespace std; int n; ]; int dfs(int n) ...

  6. 种类并查集,TOJ(1706)

    题目链接:http://acm.tju.edu.cn/toj/showp1706.html 很类似Poj的一道帮派的问题,记得找到的可疑的关系,不要将集合刷新就可以了. 1706.   A Bug's ...

  7. 通过ODBC接口访问人大金仓数据库

      国产化软件和国产化芯片的窘境一样,一方面市场已经存在性能优越的同类软件,成本很低,但小众的国产化软件不仅需要高价买入版权,并且软件开发维护成本高:另一方面,国产软件目前普遍难用,性能不稳定,Bug ...

  8. 合格PHP工程师的知识结构 (转载)

    工作有些年头了,从学校开始自学ASP,偶然因为PHP一个功能爱上它(ASP上传代码要写好多,PHP基本几行就搞定了),从此走上了 ”拍黄片“ 之路.结合这几年的工作经验,说说我对PHP工程师知识结构的 ...

  9. scrapy install

    csf@ubuntu:~$ sudo apt install python-scrapy

  10. CSS-DOM

    在所有的产品设计中,选择最适用的工具去解决问题是最基本的原则. ①使用(X)HTML去搭建文档的结构. ②使用CSS 去设置文档的呈现效果. ③使用DOM脚本去实现文档的行为. 文档中的每个元素都是一 ...