4.6 生成器Generrator

​ 生成器本质就是迭代器。python社区生成器与迭代器是一种。

​ 生成器与迭代器的唯一区别:生成器是我们自己用python代码构建的

4.6.1生成器初识

python中的生成器:

​ 1.生成器函数:使用yield语句而不是使用return语句返回结果。yield语句一次返回一个结果,在每个结果中间,挂起函数状态,下次可以从它离开的地方继续执行,一个next引导一个yield。

​ 2.生成器表达式:类似于列表推导,但是生成器返回按需产生结果的一个对象而不是一次构建一个结果列表。

本质:迭代器(自带_itr_ 和_next_方法)

特点:惰性运算

​ 3.利用python提供的一些内置函数,返回一个生成器

4.6.2 生成器函数

​ 一个包含yield关键字的函数就是一个生成器函数,用next触发,一个next对应一个yield。 只要函数中出现了yield那么他就不是函数,它是生成器函数。

def func():
yield 2, 3, 4
yield 'a'
yield [1,2,3]
ret = func() #注释1:
print(ret) #注释2:
print(next(ret))
print(next(ret))
print(next(ret))
#输出
<generator object func at 0x000001EB854B3FC0>
(2, 3, 4)
a
[1, 2, 3]

注释1:生成器对象,这里一定要声明一个变量指向生成器,直接print生成器的话,相当于在内存中新开辟空间调用生成器,print一次func() 就建立一个新的生成器,类似于多条产线同时生产一个物品一样,所以必须要有一个变量来指向生成器地址,目的是利用变量的唯一性特点。

注释2:print(ret)只是打印的ret指向的生成器地址,要显示生成器的结果,要用next来取值

4.6.3 yield 与 return的区别

​ return一般在函数中只设置一个,他的作用是终止函数,并且给函数的执行者返回值。

​ yield在生成器函数中可设置多个,他并不会终止函数,next会获取对应yield生成的元素。

4.6.4 send(了解)

send和next()区别:

​ 相同点:

​ send 和 next()都可以让生成器对应的yield向下执行一次。

​ 都可以获取到yield生成的值。

​ 不同点:

​ 第一次获取yield值只能用next不能用send(可以用send(None))。

​ send可以给上一个yield置传递值。

4.6.5 生成器举例

#1:单线程
def eat_food():
lis1 = []
for i in range(1,2001):
lis1.append(f"{i}份菜")
yield lis1 #即使yield在
s = eat_food()
print(next(s)) #输出['1份菜']
print(next(s)) #输出['1份菜', '2份菜'] #2:多线程,
def eat_food():
lis1 = []
for i in range(1,2001):
lis1.append(f"{i}份菜")
yield lis1
s = eat_food()
s1 = eat_food() #多线程下,交叉next不会冲突
print(next(s)) #输出['1份菜']
print(next(s1)) #输出['1份菜']
print(next(s)) #输出['1份菜', '2份菜']
print(next(s1)) #输出['1份菜', '2份菜'] #next配合for循环连续输出
def eat_food():
lis1 = []
for i in range(1,2001):
lis1.append(f"{i}份菜")
yield lis1
s = eat_food()
for i in range(200): #一次性输出200次
print(next(s))

4.6.6 yield与yield from

yield form可以直接把可迭代对象中的每一个数据作为生成器的结果进行返回。(python3中特有)

#先看yield
def func():
li = [1,2,3]
yield li
a = func()
print(next(a)) #输出[1, 2, 3] #再看yield form
def func():
li = [1,2,3]
yield from li #将一个可迭代对象的每一个元素返回给next
a = func()
print(next(a)) #输出 1
print(next(a)) #输出 2
print(next(a)) #输出 3

有个小坑,yield from 是将列表中的每一个元素返回,所以如果写两个yield from 并不会产生交替的效果

def func():
lst1 = ['卫龙', '老冰棍', '北冰洋', '牛羊配']
lst2 = ['馒头', '花卷', '豆包', '大饼']
yield from lst1 #输出玩lst1才能输出lst2
yield from lst2
g = func()
for i in g:
print(i)

4.6.7 列表推导式,生成器推导式

1.列表推导式
  • 列表推导式:一行代码构建一个有规律比较复杂的列表。
  • 列表推导式与之前写法对比
#普通表达式
#生成1-100的列表l1 = [1,2,3......100]
l1 = []
for i in range(1,101):
l1.append(i)
print(l1)
# 列表推导式
l1 = [i for i in range(1, 101)]
print(l1)
2.列表推导式的两种构建方式
  • ​ 循环模式: [变量(加工后的变量) for 变量 in iterable]
  • ​ 筛选模式: [变量(加工后的变量) for 变量 in iterable if 条件]
# ----------------循环模式:------------

# 将10以内所有整数的平方写入列表。
print([i**2 for i in range(1, 11)])
# 100以内所有的偶数写入列表.
print([i for i in range(2, 101, 2)])
# 从python1期到python100期写入列表list
print([f'python{i}期' for i in range(1, 101)])
# ---------------筛选模式-------------:

# 三十以内可以被三整除的数。
print([i for i in range(1, 31) if i % 3 == 0])
# 过滤掉长度小于3的字符串列表,并将剩下的转换成大写字母
l1 = ['barry', 'fdsaf', 'alex', 'sb', 'ab']
print([i.upper() for i in l1 if len(i) > 3])
# 找到嵌套列表中名字含有两个‘e’的所有名字(有难度)
names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'],
['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']]
print([j for i in names for j in i if j.count('e') > 1])

列表推导式的优缺点:

优点:

简单,快捷,装b。

缺点:

​ 可读性不高,不好排错。

​ 慎用,不要入迷。

3.生成器推导式

与列表推导式几乎一模一样,只是把[]换成()就行了。

循环模式,筛选模式。

#循环模式
tem = (i for i in range(10))
print(next(tem)) #输出 0
print(next(tem)) #输出 1
#筛选模式
tem = (i for i in range(10) if i%2==1)
print(next(tem)) #输出 1
print(next(tem)) #输出 3
#触发生成器
tem = (i for i in range(10) if i%2==1)
for i in tem:
print(i)

出发迭代器的几种方式:

​ 1.next(tem)触发

​ 2.for i in tem:

​ print(i)

​ 因为for循环内部调用了next函数

​ 3.转换生列表

​ print(list(tem))以列表的形式输出

4.6.8 字典推导式、集合推导式

两种模式: 循环模式,筛选模式

# 字典推导式
l1 = ['小潘', '小明','小红', '小强']
dic = {i:l1[i] for i in range(len(l1))}
print(dic)
#集合推到式
l1 = ['小潘', '小明','小红', '小强']
set1 = {i for i in range(len(l1))}
print(set1)

python学习之生成器的更多相关文章

  1. Python学习二(生成器和八皇后算法)

    看书看到迭代器和生成器了,一般的使用是没什么问题的,不过很多时候并不能用的很习惯 书中例举了经典的八皇后问题,作为一个程序员怎么能够放过做题的机会呢,于是乎先自己来一遍,于是有了下面这个ugly的代码 ...

  2. python学习之---生成器

    通过列表生成式,我们可以直接创建一个列表.但是,受到内存限制,列表容量肯定是有限的.而且,创建一个包含1000万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元 ...

  3. Python学习笔记 - 生成器generator

    #!/usr/bin/env python3 # -*- coding: utf-8 -*- # generator 生成器 L = [x * x for x in range(10)] print( ...

  4. Python学习——迭代器&生成器&装饰器

    一.迭代器 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退迭代器的一大优点是不要求事先准备好整个迭代过程中所有的元素.迭代器仅 ...

  5. python学习-39 生成器总结

    总结 1.语法上和函数类似:生成器函数和常规函数几乎是一样的.它们都是使用def语句进行定义,差别在于,生成器使用yield语句返回一个值,常规函数使用return语句返回一个值. 2.自动实现迭代器 ...

  6. python学习之- 生成器/迭代器

    列表生成式写法: [ i*2 for i in range(10) ]也可以带函数 [ fun(i) for i in range(10) ] 生成器:一边循环一边计算的机制称为生成器.在常用函数中, ...

  7. Python学习---装饰器/迭代器/生成器的学习【all】

    Python学习---装饰器的学习1210 Python学习---生成器的学习1210 Python学习---迭代器学习1210

  8. Python学习笔记之生成器、迭代器和装饰器

    这篇文章主要介绍 Python 中几个常用的高级特性,用好这几个特性可以让自己的代码更加 Pythonnic 哦 1.生成器 什么是生成器呢?简单来说,在 Python 中一边循环一边计算的机制称为 ...

  9. python学习10—迭代器、三元表达式与生成器

    python学习10—迭代器.三元表达式与生成器 1. 迭代器协议 定义:对象必须提供一个next方法,执行该方法或者返回迭代中的下一项,或者返回一个StopIteration异常,以终止迭代(只能往 ...

随机推荐

  1. [易学易懂系列|rustlang语言|零基础|快速入门|(15)|Unit Testing单元测试]

    [易学易懂系列|rustlang语言|零基础|快速入门|(15)] 实用知识 Unit Testing单元测试 我们知道,在现代软件开发的过程中,单元测试对软件的质量极及重要. 今天我们来看看Rust ...

  2. Linux如何将pycharm添加到桌面

    使用Ubuntu编辑器,在/usr/share/applications 目录下创建一个 Pycharm.destop的文件. sudo vim /usr/share/applications/Pyc ...

  3. POJ 1038 Bugs Integrated Inc (复杂的状压DP)

    $ POJ~1038~~\times Bugs~Integrated~Inc: $ (复杂的状压DP) $ solution: $ 很纠结的一道题目,写了大半天,就想练练手,结果这手生的.其实根据之前 ...

  4. 2019ICPC沈阳网络赛-D-Fish eating fruit(树上DP, 换根, 点分治)

    链接: https://nanti.jisuanke.com/t/41403 题意: State Z is a underwater kingdom of the Atlantic Ocean. Th ...

  5. LightOJ-1104-birthday Paradox(概率)

    链接: https://vjudge.net/problem/LightOJ-1104 题意: Sometimes some mathematical results are hard to beli ...

  6. 如何下载Direct3D9Ex

    其实就是DirectX june_10月版本,下载链接如下 DirectX Software Development Kit 错误:安装报错“S1023" 若要解决此问题,必须在安装2010 ...

  7. 清除eclipse 里面主函数的加载记录 launch configuration删除

    我们eclipse  里面执行的程序,应用 把他记录下来,生成配置文件. 当我们导出行的jar包的时候,需要制定运行的主函数. 会看到很多的历史主程序,带来方便的同时,也产生了影响. 需要清除写记录的 ...

  8. CF 672C 两个人捡瓶子 最短路与次短路思想

    C. Recycling Bottles time limit per test 2 seconds memory limit per test 256 megabytes input standar ...

  9. HGOI 20190519 题解

    脑补了一下今天的比赛难度和之前zju-lzw出的题目画风迥异. 难度完全不是一个水平的好伐. Probem A palindrome 给出一个$n$个元素的数组,可以任意指定一个数字$m$让所有$a_ ...

  10. POJ1703--Find them, Catch them(种类并查集)

    Time Limit: 1000MSMemory Limit: 10000K Total Submissions: 32909Accepted: 10158 Description The polic ...