0 前言
说到处理循环,我们习惯使用for, while等,比如依次打印每个列表中的字符:
在打印内容字节数较小时,全部载入内存后,再打印,没有问题。可是,如果现在有成千上百万条车辆行驶轨迹,叫你分析出其中每个客户的出行规律,堵车情况等,假如是在单机上处理这件事。
你可能首先要面临,也可能被你忽视,最后代码都写好后,才可能暴露出的一个问题:outofmemory, 这在实际项目中经常遇到。
这个问题提醒我们,处理数据时,如何写出高效利用内存的程序,就显得很重要。今天,我们就来探讨如何高效利用内存,节省内存同时还能把事情办好。
其实,Python已经准备好一个模块专门用来处理这件事,它就是itertools 模块,这里面几个函数的功能其实很好理解。
我不打算笼统的介绍它们所能实现的功能,而是想分析这些功能背后的实现代码,它们如何做到高效节省内存的,Python内核的贡献者们又是如何写出一手漂亮的代码的,这很有趣,不是吗?
OK,let's go. Hope you enjoy the journey!
1 拼接元素
itertools 中的chain 函数实现元素拼接,原型如下,参数*表示个数可变的参数
chain(iterables)
应用如下:
哇,不能再好用了,它有点join的味道,但是比join强,它的重点在于参数都是可迭代的实例。
那么,chain如何实现高效节省内存的呢?chain大概的实现代码如下:
以上代码不难理解,chain本质返回一个生成器,所以它实际上是一次读入一个元素到内存,所以做到最高效地节省内存。
2 逐个累积
返回列表的累积汇总值,原型:
accumulate(iterable[, func, *, initial=None])
应用如下:
accumulate大概的实现代码如下:
以上代码,你还好吗?与chain简单的yield不同,此处稍微复杂一点,yield有点像return,所以 yield total那行直接就返回一个元素,也就是iterable的第一个元素,因为任何时候这个函数返回的第一个元素就是它的第一个。又因为yield返回的是一个generator对象,比如名字gen,所以next(gen)时,代码将会执行到 for element in it:这行,而此时的迭代器it 已经指到iterable的第二个元素,OK,相信你懂了!
3 漏斗筛选
它是compress 函数,功能类似于漏斗功能,所以我称它为漏斗筛选,原型:
compress(data, selectors)
容易看出,compress返回的元素个数等于两个参数中较短的列表长度。
它的大概实现代码:
这个函数非常好用
4 段位筛选
扫描列表,不满足条件处开始往后保留,原型如下:
dropwhile(predicate, iterable)
应用例子:
实现它的大概代码如下:
5 段位筛选2
扫描列表,只要满足条件就从可迭代对象中返回元素,直到不满足条件为止,原型如下:
takewhile(predicate, iterable)
应用例子:
实现它的大概代码如下:
6 次品筛选
扫描列表,只要不满足条件都保留,原型如下:
dropwhile(predicate, iterable)
应用例子:
实现它的大概代码如下:
7 切片筛选
Python中的普通切片操作,比如:
它们的缺陷还是lis 必须全部载入内存,所以更节省内存的操作islice,原型如下:
islice(iterable, start, stop[, step])
应用例子:
实现它的大概代码如下:
巧妙利用生成器迭代结束时会抛出异常StopIteration,做一些边界处理的事情。
8 细胞分裂
tee函数类似于我们熟知的细胞分裂,它能复制原迭代器n个,原型如下:
tee(iterable, n=2)
应用如下,可以看出复制出的两个迭代器是独立的
实现它的代码大概如下:
tee 实现内部使用一个队列类型deques,起初生成空队列,向复制出来的每个队列中添加元素newval, 同时yield 当前被调用的mydeque中的最左元素。
9 map变体
starmap可以看做是map的变体,它能更加节省内存,同时iterable的元素必须也为可迭代对象,原型如下:
starmap(function, iterable)
应用它:
starmap的实现细节如下:
10 复制元素
repeat实现复制元素n次,原型如下:
repeat(object[, times])
应用如下:
它的实现细节大概如下:
11 笛卡尔积
笛卡尔积实现的效果同下:
所以,笛卡尔积的实现效果如下:
它的实现细节:
12 加强版zip
组合值。若可迭代对象的长度未对齐,将根据 fillvalue 填充缺失值,注意:迭代持续到耗光最长的可迭代对象,效果如下:
它的实现细节:
它里面使用repeat,也就是在可迭代对象的长度未对齐时,根据 fillvalue 填充缺失值。理解上面代码的关键是迭代器对象(iter),next方法的特殊性:
结合这个提示再理解上面代码,就不会吃力。
对于想学python的小伙伴,我这里整理了一套自己的python系统学习教程,
想要这些资料的可以关注私信“资料”领取资料,希望能对你有所帮助。
本套教程学习时间15天
1-3天内容:为Linux基础命令
4-13天内容:为Python基础教程14-15 天内容:为飞机大战项目演练
第一阶段(1-3天):
该阶段首先通过介绍不同领域的三种操作系统,操作系统的发展简史以及Linux系统的文件目录结构让大家对Linux系统有一个简单的认识,同时知道为什么要学习Linux命令。然后我们会正式学习Linux命令
1. 文件和目录命令:ls,cd,touch,mkdir,rm
2. 拷贝和移动命令:tree,cp,mv
3. 文件内容命令:cat,more,grep
4. 远程管理命令:ifconfig,ping,SSH的工作方式简介以及ssh命令
5. 用户权限及用户管理命令:chmod,chgrp,useradd,passwd,userdel
6. 软件安装及压缩命令:apt简介及命令,tar,gzip压缩命令,bzip2压缩命令
7. vim的基本使用
第二阶段(4-10天)
该阶段我们正式进入Python这门语言的学习,首先通过了解Python语言的起源,Python语言的设计目标,Python语言的设计哲学,Python语言的优缺点和面向对象的基本概念,以及Python语言的执行方式,还有Python集成开发环境PyCharm的使用为我们接下来的学习做铺垫。
然后我们会学习int,string,float三种简单的变量类型,变量间的计算,变量的输入输出,if判断语句,while循环语句,for循环语句,break和continue的使用,函数的基本使用,模块的使用,列表,元组,字典三种高级变量,字符串的常用操作。
接下来我们会通过一个名片管理系统的案例,把这一阶段的知识进行一个串联。在学习名片管理系统时,首先我们会学习怎么去搭建这一系统的框架,然后我们会分别实现新增名片,显示全部名片,查询名片,删除名片,修改名片这些功能。
最后我们会学习语法的进阶内容,全局变量,局部变量,可变数据类型和不可变数据类型以及函数返回多个值,函数的缺省参数,多值参数,递归的基本使用。
第三阶段(11-13天)
该阶段我们会学习面向对象(OOP)这一重要的编程思想,首先学习的知识点有类和对象的基本概念,dir函数,self的作用,初始化方法__init__,内置函数__str__,__del__,单继承,方法重写,私有属性和方法,多继承,多态,类属性,静态方法。
然后我们还会学习单例模式这一设计模式,异常的捕获,异常的抛出,from import局部导入,from import导入同名工具, from import导入所有工具,包的使用,制作模块,pip的使用以及文件的相关操作。
第四阶段(14-15天)
该阶段是项目演练阶段,我们会带领大家通过使用之前学习过的知识开发飞机大战这一经典游戏,项目中分别有游戏窗口,图像绘制,游戏循环,事件监听,精灵和精灵组以及创建敌机,创建英雄和发射子弹,碰撞检测等模块。
转发文章+私信小编(资料)即可领取以下学习教程!
下面是北京大学毕业的高琪老师亲手打造的python学习路线和视频。共分为7大阶段.
获取在文末!!!
第一阶段
python开发基础和核心特性
1.变量及运算符
2.分支及循环
3.循环及字符串
4.列表及嵌套列表
5.字典及项目练习
6.函数的使用
7.递归及文件处理
8.文件
9.面向对象
10.设计模式及异常处理
11.异常及模块的使用
12.坦克大战
13.核心编程
14.高级特性
15.内存管理
第二阶段
数据库和linux基础
1.并发编程
2.网络通信
3.MySQL
4.Linux
5.正则表达式
第三阶段
web前端开发基础
1.html基本标签
2.css样式
3.css浮动和定位
4.js基础
5.js对象和函数
6.js定时器和DOM
7.js事件响应
8.使用jquery
9.jquery动画特效
10.Ajax异步网络请求
第四阶段
Python Web框架阶段
1.Django-Git版本控制
2.Django-博客项目
3.Django-商城项目
4.Django模型层
5.Django入门
6.Django模板层
7.Django视图层
8.Tornado框架
第五阶段
Python 爬虫实战开发
1.Python爬虫基础
2.Python爬虫Scrapy框架
以上这python自学教程小编已经为大家打包准备好了,希望对正在学习的你有所帮助!