列表生成式

通过上一篇介绍 列表生成式文章可以知道,它可以快速创建我们需要的列表

局限性

  • 受内存限制,列表生成式创建的列表的容量肯定有限的
  • 不仅占用很大的存储空间,如果我们仅仅需要访问前几个元素,那后面绝大多数元素占用的空间都白白浪费了

什么是生成器

  • 若列表元素可以按照某种算法算出来,就可以在循环的过程中不断推算出后续需要用的元素,而不必创建完整的 list,从而节省大量的空间
  • 边循环边计算的机制,叫生成器(generator)

最简单的生成器

L = [x * x for x in range(10)]
print(L)
print(type(L)) L = (x * x for x in range(10))
print(L)
print(type(L)) # 输出结果
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
<class 'list'>
<generator object <genexpr> at 0x000001D607541EB8>
<class 'generator'>

只要把一个列表生成式的 [] 改成 () ,就创建了一个 generator

如何打印生成器每个元素

直接简单 for 循环

L2 = (x * x for x in range(10))

for i in L2:
print(i)

next() 方法

可以获取 generator 的下一个元素

基本不会使用这个

L2 = (x for x in range(10))
print(next(L2))
print(next(L2))
print(next(L2))
print(next(L2))
print(next(L2))
print(next(L2)) # 输出结果
0
1
2
3
4
5

还有另一个方法 .__next()__

L2 = (x for x in range(10))
print(L2.__next__())
print(L2.__next__())
print(L2.__next__())
print(L2.__next__())
print(L2.__next__())
print(L2.__next__()) # 输出结果
0
1
2
3
4
5

生成器的迭代原理

generator 能够迭代的关键就是 next() 方法,通过重复调用 next() 方法,直到捕获一个异常

yield 函数

  • 带有 yield 的函数不再是一个普通函数,而是一个生成器 generator
  • yield 相当于 return 返回一个值,并且记住这个返回值的位置,下次迭代时,代码会从 yield 的下一条语句开始执行,直到函数结束或遇到下一个 yield

普通的斐波拉契数列

1, 1, 2, 3, 5, 8, 13, 21, 34, ...,除第一个和第二个数外,任意一个数都可由前两个数相加得到

# 斐波拉契数列
def fib(max):
n, a, b = 0, 0, 1
while n < max:
print(b)
a, b = b, a + b
n = n + 1 fib(8) # 输出结果
1
1
2
3
5
8
13
21

它和生成器很像,知道第一个元素值,就可以推算后面的任意个元素了

是用 yield 的斐波拉契数列

def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
n = n + 1 fib(8)
print(fib(8)) # 输出结果
1
1
2
3
5
8
13
21
<generator object fib at 0x00000246A5001EB8>

生成器的执行流程

函数是顺序执行,遇到 return 或者最后一行执行完就返回

而生成器的执行流程是

  • 每次调用 next() 或 for 循环的时候执行,遇到 yield 就返回
  • 一个生成器里面可以有多个 yield
  • 再次执行时从上次返回的 yield 语句处继续执行
# 执行流程
def odd():
print('step 1')
yield 1
print('step 2')
yield 3
print('step 3')
yield 5 L = odd()
for i in L:
print(i) # 输出结果
step 1
1
step 2
3
step 3
5

生成器的工作原理

  • 它是在 for 循环过程中不断计算下一个元素,并在适当的条件结束 for 循环
  • 对于函数改成的 generator 来说,,遇到 return 语句或者执行到函数最后一行时,就是结束 generator 的指令,for 循环随之结束

生成器的优点

在不牺牲过多速度情况下,释放了内存,支持大数据量的操作

不使用生成器下的代码

from tqdm import tqdm

a = []
for i in tqdm(range(10000000)):
temp = ['你好'] * 2000
a.append(temp) for ele in a:
continue

运行结果

可以看到开始运行大数据量循环代码后,内存暴增,并且占满了电脑所有内存,很明显这是不合理且不可接受的!

使用生成器的代码

def test():
for i in tqdm(range(10000000)):
temp = ['你好'] * 2000
yield temp a = test()
for ele in a:
continue

运行结果

内存丝滑的很,奈斯!

生成器的应用场景

当然就是需要处理大数据量的场景了,比如一个文件有几百万行数据,或者有几百万个文件需要分别读取处理

Python 高级特性(4)- 生成器的更多相关文章

  1. 三、python高级特性(切片、迭代、列表生成器、生成器)

    1.python高级特性 1.1切片 list列表 L=['Mli','add','sal','saoo','Lkkl'] L[0:3]  #即为['Mli','add','sal']  从索引0开始 ...

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

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

  3. Python高级特性(2):Closures、Decorators和functools(转)

    原文:Python高级特性(2):Closures.Decorators和functools 装饰器(Decorators) 装饰器是这样一种设计模式:如果一个类希望添加其他类的一些功能,而不希望通过 ...

  4. Python高级特性(1):Iterators、Generators和itertools(转)

    译文:Python高级特性(1):Iterators.Generators和itertools [译注]:作为一门动态脚本语言,Python 对编程初学者而言很友好,丰富的第三方库能够给使用者带来很大 ...

  5. Python高级特性之:List Comprehensions、Generator、Dictionary and set ...

    今天帅气的易哥和大家分享的是Pyton的高级特性,希望大家能和我一起学习这门语言的魅力. Python高级特性之:List Comprehensions.Generator.Dictionary an ...

  6. Python 高级特性介绍 - 迭代的99种姿势 与协程

    Python 高级特性介绍 - 迭代的99种姿势 与协程 引言 写这个笔记记录一下一点点收获 测试环境版本: Python 3.7.4 (default, Sep 28 2019, 16:39:19) ...

  7. python高级特性和高阶函数

    python高级特性 1.集合的推导式 列表推导式,使用一句表达式构造一个新列表,可包含过滤.转换等操作. 语法:[exp for item in collection if codition] if ...

  8. Python高级编程之生成器(Generator)与coroutine(二):coroutine介绍

    原创作品,转载请注明出处:点我 上一篇文章Python高级编程之生成器(Generator)与coroutine(一):Generator中,我们介绍了什么是Generator,以及写了几个使用Gen ...

  9. Python高级特性(3): Classes和Metaclasses(转)

    原文:Python高级特性(3): Classes和Metaclasses 类和对象 类和函数一样都是Python中的对象.当一个类定义完成之后,Python将创建一个“类对象”并将其赋值给一个同名变 ...

  10. Python高级特性(切片,迭代,列表生成式,生成器,迭代器)

    掌握了Python的数据类型.语句和函数,基本上就可以编写出很多有用的程序了. 比如构造一个1, 3, 5, 7, ..., 99的列表,可以通过循环实现: L = [] n = 1 while n ...

随机推荐

  1. Redis 博文索引

    博文索引 Redis 对象与编码 Redis 持久化 Redis 主从复制 Redis 哨兵 Redis 缓存淘汰 Redis 集合统计 Redis 简介

  2. springboot项目启动后tomcat服务器自动关闭 解决方法

    需要在pom.xml中添加 <dependency> <groupId>org.springframework.boot</groupId> <artifac ...

  3. idea将文件push之后如何回退

  4. 第49天学习打卡(CSS 层次选择器 结构伪类选择器 属性选择器 美化网页元素 盒子模型)

    推荐书籍:码出高效: Java 开发手册 2.2 层次选择器 idea里代码规范是按:ctrl +alt+L快捷键 注释快捷键:ctrl+/ 1.后代选择器:在某个元素的后面 祖爷爷 爷爷 爸爸 你 ...

  5. brew安装Nginx

    目录 安装流程 常用命令记录 典型配置方式 查看启动状态是否有报错 php 启动 参考 安装流程 这里使用 brew 来安装软件. 安装 brew install nginx 查看安装信息(经常用到, ...

  6. MySQL数据库插入数据出现 ERROR 1526 (HY000): Table has no partition for value xxx

    MySQL数据库插入数据出现ERROR 1526 (HY000): Table has no partition for value xxx工作的时候发现无法插入数据,报错:ERROR 1526 (H ...

  7. 25个关键技术点,带你熟悉Python

    摘要:本文收纳了Python学习者经常使用的库和包,并介绍了Python使用中热门的问题. 01.Python 简介 什么是 Python 一种面向对象的高级动态可解释型脚本语言. Python 解释 ...

  8. JS(ES6)、Vue.js、node.js

    JS行为(ESMAScript, JSdom, bom)$.ajax() <- (xmlhttpRequest由这个封装来的)  -> axios(vue版)  =  ajax技术jque ...

  9. C# 应用 - 使用 HttpListener 接受 Http 请求

    1. 库类: \Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6\System.dll System.Net.HttpListen ...

  10. WPF 基础 - DataTemplate

    如果把控件的功能视为内容,则可以使用控件模板 ControlTemplate 来控制它的展现: 如果把数据视为内容,则可以使用数据模板 DataTemplate 把数据展示出来: ControlTem ...