Python 节省内存的循环写法 (一)_python循环读取文件的每一行 节省内存-程序员宅基地

技术标签: RPA教程  python基础  RPA  RPA10.0  艺赛旗  Python  

艺赛旗 RPA9.0全新首发免费下载 点击下载
http://www.i-search.com.cn/index.html?from=line1

0 前言

说到处理循环,我们习惯使用 for, while 等,比如依次打印每个列表中的字符:

lis = [‘I’, ‘love’, ‘python’]
for i in lis:
print(i)
输出:

I
love
python
在打印内容字节数较小时,全部载入内存后,再打印,没有问题。可是,如果现在有成千上百万条车辆行驶轨迹,叫你分析出其中每个客户的出行规律,堵车情况等,假如是在单机上处理这件事。
你可能首先要面临,也可能被你忽视,最后代码都写好后,才可能暴露出的一个问题:outofmemory, 这在实际项目中经常遇到。
这个问题提醒我们,处理数据时,如何写出高效利用内存的程序,就显得很重要。今天,我们就来探讨如何高效利用内存,节省内存同时还能把事情办好。

其实,Python 已经准备好一个模块专门用来处理这件事,它就是 itertools 模块,这里面几个函数的功能其实很好理解。
我不打算笼统的介绍它们所能实现的功能,而是想分析这些功能背后的实现代码,它们如何做到高效节省内存的,Python 内核的贡献者们又是如何写出一手漂亮的代码的,这很有趣,不是吗?

1 拼接元素

itertools 中的 chain 函数实现元素拼接,原型如下,参数 * 表示个数可变的参数

chain(iterables)

应用如下:

In [33]: list(chain([‘I’,‘love’],[‘python’],[‘very’, ‘much’]))
Out[33]: [‘I’, ‘love’, ‘python’, ‘very’, ‘much’]
哇,不能再好用了,它有点 join 的味道,但是比 join 强,它的重点在于参数都是可迭代的实例。

那么,chain 如何实现高效节省内存的呢?chain 大概的实现代码如下:

def chain(*iterables):
for it in iterables:
for element in it:
yield element
以上代码不难理解,chain本质返回一个生成器,所以它实际上是一次读入一个元素到内存,所以做到最高效地节省内存。

2 逐个累积

返回列表的累积汇总值,原型:
accumulate(iterable[, func, *, initial=None])

应用如下:

In [36]: list(accumulate([1,2,3,4,5,6],lambda x,y: x*y))
Out[36]: [1, 2, 6, 24, 120, 720]
accumulate 大概的实现代码如下:

def accumulate(iterable, func=operator.add, *, initial=None):
it = iter(iterable)
total = initial
if initial is None:
try:
total = next(it)
except StopIteration:
return
yield total
for element in it:
total = func(total, element)
yield total
以上代码,你还好吗?与 chain 简单的 yield 不同,此处稍微复杂一点,yield 有点像 return,所以 yield total那行直接就返回一个元素,也就是 iterable 的第一个元素,因为任何时候这个函数返回的第一个元素就是它的第一个。又因为 yield 返回的是一个 generator 对象,比如名字 gen,所以 next(gen) 时,代码将会执行到 for element in it:这行,而此时的迭代器 it 已经指到 iterable 的第二个元素,OK,相信你懂了!

3 漏斗筛选

它是 compress 函数,功能类似于漏斗功能,所以我称它为漏斗筛选,原型:

compress(data, selectors)

In [38]: list(compress(‘abcdefg’,[1,1,0,1]))
Out[38]: [‘a’, ‘b’, ‘d’]
容易看出,compress 返回的元素个数等于两个参数中较短的列表长度。
它的大概实现代码:

def compress(data, selectors):
return (d for d, s in zip(data, selectors) if s)
4 段位筛选

扫描列表,不满足条件处开始往后保留,原型如下:

dropwhile(predicate, iterable)
应用例子:

In [39]: list(dropwhile(lambda x: x<3,[1,0,2,4,1,1,3,5,-5]))
Out[39]: [4, 1, 1, 3, 5, -5]
实现它的大概代码如下:

def dropwhile(predicate, iterable):
iterable = iter(iterable)
for x in iterable:
if not predicate(x):
yield x
break
for x in iterable:
yield x
5 段位筛选 2

扫描列表,只要满足条件就从可迭代对象中返回元素,直到不满足条件为止,原型如下:

takewhile(predicate, iterable)

应用例子:

In [43]: list(takewhile(lambda x: x<5, [1,4,6,4,1]))
Out[43]: [1, 4]
实现它的大概代码如下:

def takewhile(predicate, iterable):
for x in iterable:
if predicate(x):
yield x
else:
break #立即返回
6 次品筛选

扫描列表,只要不满足条件都保留,原型如下:

dropwhile(predicate, iterable)

应用例子:

In [40]: list(filterfalse(lambda x: x%2==0, [1,2,3,4,5,6]))
Out[40]: [1, 3, 5]

实现它的大概代码如下:

def dropwhile(predicate, iterable):
iterable = iter(iterable)
for x in iterable:
if not predicate(x):
yield x
break
for x in iterable:
yield x

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_44447687/article/details/103255379

智能推荐

Mybatis常用标签详解_mybatis标签详解-程序员宅基地

文章浏览阅读1.1w次,点赞29次,收藏167次。MyBatis 真正强大在于它的语句映射,这是它的魔力所在。由于它的异常强大,映射器的 XML文件就显得相对简单。如果拿它跟具有相同功能的 JDBC 代码进行对比,你会立即发现省掉了将近 95% 的代码。MyBatis致力于减少使用成本,让用户能更专注于 SQL 代码。_mybatis标签详解

Android 监听音频焦点变化-程序员宅基地

文章浏览阅读468次,点赞22次,收藏16次。在 Android 中,监听音频焦点变化意味着您可以获得关于音频焦点状态的通知,并针对焦点变化执行相应的操作。音频焦点是指哪个应用程序或组件有权播放音频的能力。

Linux基础之初识SHELL脚本_shell脚本-gf-程序员宅基地

文章浏览阅读10w+次。Shell脚本(Shell Script )可以简单理解为多个LINUX命令的堆砌,与Windows/Dos下的批处理相似_shell脚本-gf

IPD思想指导下的企业研发管理成熟度演进模型-程序员宅基地

文章浏览阅读2.4k次。基于IPD研究(书籍、网络文章、个人实践),参考CMMI框架,输出本研发管理能力成熟度框架。_研发管理成熟度

linux下Js加载so,JavaScript文件加载器LABjs API详解-程序员宅基地

文章浏览阅读478次。在《高性能JavaScript》一书中提到了LABjs这个用来加载JavaScript文件的类库,LABjs是Loading And Blocking JavaScript的缩写,顾名思义,加载和阻塞JavaScript,而它的API script()和wait()则优雅地实现了这两个功能,我在高性能JavaScript 加载和执行一文中也简单讲解了这两个核心API的用法。当然,LABjs还有更多..._so打包到js

Rancher 1.6 实战-程序员宅基地

文章浏览阅读1.7k次。为什么80%的码农都做不了架构师?>>> ..._rancher 1.6

随便推点

2021-08-03以CSU18MB86芯片做主控开发打气泵方案_csu18p88 气泵方案-程序员宅基地

文章浏览阅读170次。  汽车轮胎打气泵方案功能介绍:    显示方式:LED显示,测量和设置同屏显示。    单位:4个,循环切换顺序PSI、KPA、 Bar、 Kg/cm2    测量范围:    3.0 ~ 150.0PSI; 20 ~ 1030KPA    0.2 ~ 10.30Bar; 0.2 ~ 10.50Kg/cm2    设置范围:    3 ~ 120PSI; 20 ~ 825KPA    0.2 ~ 8.25Bar; 0.2 ~ 10.50 Kg/cm2    测量精度:+_csu18p88 气泵方案

ansible的安装与使用_ansible 认不到已经安装的python-netaddr-程序员宅基地

文章浏览阅读112次。# 安装epel库# yum -y install epel-release# 安装pip,python3自带pip3# yum -y install python-pip# 升级pippip install --upgrade pip# 检查版本pip --versionpip 19.0.3 from /usr/lib/python2.7/site-packages/pip (p..._ansible 认不到已经安装的python-netaddr

sonar-程序员宅基地

文章浏览阅读61次。1.maven的setting.xml中<profiles> <profile> <id>sonar</id> <activation> <activeByDefault>true</activeByDefault> </activation> <proper...

linux mysql源,linux 安装 mysql8+ rpm源方式-程序员宅基地

文章浏览阅读137次。系统 更新yum upgrade卸载rpm -qa|grep -i mysqlrpm -ev mysql-community-common-5.7.27-1.el7.x86_64 mysql-community-server-5.7.27-1.el7.x86_64 mysql-community-server-5.7.27-1.el7.x86_64 mysql-community-libs-5.7..._yum拉取msyql8的rpm源

Java Reflection Tutorial for Classes, Methods, Fields, Constructors, Annotations and much more_reports all fields methods 哦日期classes,found in the-程序员宅基地

文章浏览阅读1k次。Reflection in java provides ability to inspect and modify the runtime behavior of applications. Reflection is one of the advance topic of core java. Using reflection we can inspect a class,interface_reports all fields methods 哦日期classes,found in the specified

HomeAssistant实现对UPS的数据监控_network ups tools-程序员宅基地

文章浏览阅读4.4k次。之前写在《米家接入HomeKit系列》系列文章的时候,我们讲解了如何使用通过HomeAssistant和HomeBridge来将米家设备接入HomeKit中。细心的同学应该发现我在讲解米家接入HomeKit系列二:通过群辉NAS的Docker搭建HomeAssistant章节最后的配置截图中有个UPS的配置。于是就有玩NAS的小伙伴问我UPS如何接入HomeAssistant。那么今天我就特意写一篇文章给大家介绍下我们怎样才能够将UPS接入到HomeAssistant中进行展示监控。_network ups tools

推荐文章

热门文章

相关标签