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. 第二章 Vue快速入门--20 品牌案例-完成品牌列表的添加功能+ 21 品牌案例-根据Id完成品牌的删除

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...

  2. String中的intern方法

    上一篇你真的会用String吗(3)-关于字符串拼接中我们提到了String.intern()方法,本篇我们就来详细的看下这个方法是干嘛的.首先来看下jdk8中这个方法的注释: When the in ...

  3. 【UOJ#37】 [清华集训2014] 主旋律

    题目链接 题目描述 给定一张强联通图,求有多少种边的存在情况满足图依然强联通. \(n\leq15\) Sol 首先正难则反,考虑用总数减去不强联通的. 考虑一张不强联通的图,缩点后一定是一个 DAG ...

  4. mysql数据库之 存储引擎、事务、视图、触发器、存储过程、函数、流程控制、数据库备份

    目录 一.存储引擎 1.什么是存储引擎? 2.mysql支持的存储引擎 3. 使用存储引擎 二.事务 三.视图 1.什么是视图 2.为什么要用视图 3.如何用视图 四.触发器 为何要用触发器 创建触发 ...

  5. 初学者的springmvc笔记02

    springmvc笔记 springmvc拦截器,spring类型转换,spring实现文件上传/下载 1.SpringMVC标准配置 导入jar包:core contaner 在web.xml文件中 ...

  6. docker部署jar工程

    1.把要部署的功能打成jar 工程目录结构 pom文件 <?xml version="1.0" encoding="UTF-8"?> <pro ...

  7. ReactJS 结合 antd-mobile 开发 h5 应用基本配置

    在 ReactJS 较为初级的使用 antd-mobile 使用时候直接加载 node_modules 文件中的相关 CSS,这个使用方法效率低:更高明的方法则按需加载,需要设置如下: 在 packa ...

  8. 安装Dubbo 并且安装注册中心(Zookeeper-3.3.6)

    安装zookeeper 安装Tomcat 载dubbo-admin-2.5.4.war 进入Apache ZooKeeper官方网站进行下载,https://zookeeper.apache.org/ ...

  9. log4j动态配置参数

    特别提示:本人博客部分有参考网络其他博客,但均是本人亲手编写过并验证通过.如发现博客有错误,请及时提出以免误导其他人,谢谢!欢迎转载,但记得标明文章出处:http://www.cnblogs.com/ ...

  10. idea 更新后和新的直接安装前,都需要配置 idea64.exe.vmoptions 后再使用

    配置合适的参数提升性能,默认的性能不高