认识

Python 的itertools模块提供了很多节省内存的高效迭代器, 尤其解决了一些关于数据量太大而导致内存溢出(outofmemory)的场景.

我们平时用的循环绝大多数是这样的.

# while 循环: 求1+2+...100
s, i = 0, 1
while i <= 100:
s += i
i += 1
print('while-loop: the some of 1+2+..100 is:', s) # for 循环
s = 0
for i in range(101):
s += i
print('for-loop: the some of 1+2+..100 is:', s)
while-loop: the some of 1+2+..100 is: 5050
for-loop: the some of 1+2+..100 is: 5050

但如果数据量特别大的话就凉凉了, 所以引入了itertools,迭代器, 类似于懒加载的思想

常用API

  • chain()
  • groupby()
  • accumulate()
  • compress()
  • takewhile()
  • islice()
  • repeat()

chain 拼接元素

  • 把一组迭代对象串联起来,形成一个更大的迭代器:
# join / split
s = "If you please draw me a sheep?" s1 = s.split() s2 = "-".join(s1) print("split->:", s1)
print("join->:", s2)
split->: ['If', 'you', 'please', 'draw', 'me', 'a', 'sheep?']
join->: If-you-please-draw-me-a-sheep?
import itertools
# chain
s = itertools.chain(['if', 'you'], ['please draw', 'me', 'a'], 'shape')
s
<itertools.chain at 0x1d883602240>
list(s)
['if', 'you', 'please draw', 'me', 'a', 's', 'h', 'a', 'p', 'e']

不难发现, 这就是迭代器嘛, 真的没啥.跟join差不多. 那么它是如何节省内存的呢, 其实就是一个简单的迭代器思想, 一次读取一个元素进内存,这样就高效节约内存了呀

def chain(*iterables):
for iter_ in iterables:
for elem in iter_:
yield elem

groupby 相邻元素

  • 把迭代器中相邻的重复元素挑出来放在一
# 只要作用于函数的两个元素返回的值相等,这两个元素就被认为是在一组的,而函数返回值作为组的key
for key, group in itertools.groupby('AAABBBCCAAAdde'):
print(key, list(group))
A ['A', 'A', 'A']
B ['B', 'B', 'B']
C ['C', 'C']
A ['A', 'A', 'A']
d ['d', 'd']
e ['e']
# 忽略大小写
for key, group in itertools.groupby('AaaBBbcCAAa', lambda c: c.upper()):
print(key, list(group))
A ['A', 'a', 'a']
B ['B', 'B', 'b']
C ['c', 'C']
A ['A', 'A', 'a']

accumulate 累积汇总

list(itertools.accumulate([1,2,3,4,5], lambda x,y: x*y))
[1, 2, 6, 24, 120]
# 伪代码
def accumulate(iterable, func=None, *, initial=None):
iter_ = iter(iterable)
ret = initial
# 循环迭代
if initial is None:
try:
ret = next(iter_)
except StopIteration:
return
yield ret
# 遍历每个元素, 调用传入的函数去处理
for elem in iter_:
ret = func(elem)
yield ret

compress 过滤

list(itertools.compress('youge', [1,0,True,3]))
['y', 'u', 'g']
def compress(data, selectors):
for d, s in zip(data, selectors):
if s:
return d # demo
for data, key in zip([1,2], 'abcd'):
print(data,key)
if key:
print(data)
1 a
1
2 b
2
# Pythonic
def compress(data, selectors):
return (d for d, s in zip(data, selectors) if s) # tset
ret = compress(['love', 'you', 'forever'], ['love', None, 'dd', 'forever'])
print(ret)
print(list(ret))
<generator object compress.<locals>.<genexpr> at 0x000001D8831498E0>
['love', 'forever']

生成器

  • 在类中实现了iter()方法和next()方法的对象即生成器
  • 代码上有两种形式: 元组生成器 或者 函数中出现 yield 关键字

zip

  • 对应位置进行元素拼接, 当最短的匹配上了, 则停止, 也被称为"拉长函数"

take-while

  • takewhile: 依次迭代, 满足条件则返回, 继续迭代, 一旦不满足条件则退出
# takewhile
s1 = list(itertools.takewhile(lambda x:x<=2, [0,3,2,1,-1,3,0]))
print(s1) s2 = list(itertools.takewhile(lambda x:x<5, [1,4,6,4,1,3]))
print(s2) # dropwhile
s3 = list(itertools.filterfalse(lambda x:x%2==0, range(10)))
print(s3)
[0]
[1, 4]
[1, 3, 5, 7, 9]
def take_while(condition, iter_obj):
for elem in iter_obj:
if conditon(elem):
yield elem
else:
break

dropwhile: 不满足条件的则返回

islice 切片

# 普通的切片,也是要先全部读入内存
# 注意是深拷贝的哦
l = [1,2,3,4,5]
print(l[::--1]) # generator 方式
# 默认的 start, stop, step, 只能传0或正数, 但可以自己改写的呀
list(itertools.islice(l, 0,3,1)) s = slice(3,4,5) # 只接收3个参数
s.start
s.stop
[1, 2, 3, 4, 5]
[1, 2, 3]
3
4

import sys

def slice(iter_obj, *args):
s = slice(*args) start = s.start or 0
stop = s.stop or sys.maxsize # 很大的常量
step = s.step or 1
# 构成可迭代的对象(下标)
iter_ = iter(range(start, stop, step))
try:
next_i = next(iter_)
except StopIteration:
# for i, elem n zip(range(start), iter_obj):
pass
return
try:
i, elem in enumerate(iter_obj):
if i == next_i:
yield elem
next_i = next(elem)
except StopIteration:
pass
[1, 2, 3, 4, 5]

repeat

list(itertools.repeat(['youge'], 3))
[['youge'], ['youge'], ['youge']]

def repeat(obj, times=None):
if times is None:
while True: # 一直返回
yield obj
else:
for i in range(times):
yield obj

pythonic-迭代器函数-itertools的更多相关文章

  1. Python3标准库:itertools迭代器函数

    1. itertools迭代器函数 itertools包括一组用于处理序列数据集的函数.这个模块提供的函数是受函数式编程语言(如Clojure.Haskell.APL和SML)中类似特性的启发.其目的 ...

  2. 这段代码很Pythonic | 相见恨晚的 itertools 库

    前言 最近事情不是很多,想写一些技术文章分享给大家,同时也对自己一段时间来碎片化接受的知识进行一下梳理,所谓写清楚才能说清楚,说清楚才能想清楚,就是这个道理了. 很多人都致力于把Python代码写得更 ...

  3. python迭代器以及itertools模块

    迭代器 在python中,迭代器协议就是实现对象的__iter()方法和next()方法,其中前者返回对象本身,后者返回容器的下一个元素.实现了这两个方法的对象就是可迭代对象.迭代器是有惰性的,只有在 ...

  4. 迭代器模块 itertools

    无限迭代器 itertools 包自带了三个可以无限迭代的迭代器.这意味着,当你使用他们时,你要知道你需要的到底是最终会停止的迭代器,还是需要无限地迭代下去. 这些无限迭代器在生成数字或者在长度未知的 ...

  5. python基础===Python 迭代器模块 itertools 简介

    本文转自:http://python.jobbole.com/85321/ Python提供了一个非常棒的模块用于创建自定义的迭代器,这个模块就是 itertools.itertools 提供的工具相 ...

  6. CodeForces 670E Correct Bracket Sequence Editor(list和迭代器函数模拟)

    E. Correct Bracket Sequence Editor time limit per test 2 seconds memory limit per test 256 megabytes ...

  7. Python迭代器包itertools(转)

    原文:http://www.cnblogs.com/vamei/p/3174796.html 作者:Vamei 在循环对象和函数对象中,我们了解了循环器(iterator)的功能.循环器是对象的容器, ...

  8. Python迭代器(函数名的应用,新版格式化输出)

    1. 函数名的运用 ​ 你们说一下,按照你们的理解,函数名是什么? ​ 函数名的定义和变量的定义几乎一致,在变量的角度,函数名其实就是一个变量,具有变量的功能:可以赋值:但是作为函数名他也有特殊的功能 ...

  9. Python标准库:迭代器Itertools

    Infinite Iterators: Iterator Arguments Results Example count() start, [step] start, start+step, star ...

随机推荐

  1. cube.js 最近的一些更新

    cube.js 是一个和不错的数据分析框架,最近又有了一些新的功能支持,以下是一些简单的 总结 基于web socket 的预览支持 react hooks api 支持 支持基于reecharts ...

  2. xsxs

    import subprocess compilePopen = subprocess.Popen('gcc haha',shell=True,stderr=subprocess.PIPE) comp ...

  3. xcode: {} 花括号缩进一个空格

    if (jsonDict.HasParseError()) { //前面总是有一个空格 CCLOG("GetParseError %d\n",jsonDict.GetParseEr ...

  4. [HeadFrist-HTMLCSS学习笔记]第七、八章

    [HeadFrist-HTMLCSS学习笔记]第七章CSS入门:加一点样式 重点噻 段落添加背景颜色 p{ background-color: red; } 文本颜色 p{ color: ,maroo ...

  5. Beta/Gamma事后分析

    目录 设想和目标 计划 资源 变更管理 设计/实现 测试/发布 团队的角色,管理,合作 总结 对照敏捷开发的原则, 你觉得你们小组做得最好的是哪几个原则? 请列出具体的事例. 照片 设想和目标 我们的 ...

  6. cad.net vs调试问题 20190923增加默认启动注册表,20191007更新vs2019到16.3.2

    Acad2008和Acad2010需要修改安装目录下的acad.exe.config文件内容,才可以捕获断点: <configuration> <startup> <!- ...

  7. html5 audio标签微信部分苹果手机不能自动播放音乐终极解决方案

    html5 audio标签微信部分苹果手机不能自动播放音乐终极解决方案 大家都知道需要在点击时候后 播放 ps:如果点击ajax 回来播放也不行,必须点击立即播放 要背景自动播放只能采取下面方案< ...

  8. go 语言的一个赋值操作

    最近在看client-go源码,在源码的\tools\caches\store.go文件中有一行代码不得其解(如下标黄内容),它将一个struct赋值给了一个interface type Store ...

  9. 59 网络编程(一)——端口与InetSocketAddress

    端口与几个CMD命令 公认端口:0-1023 比如80端口分配给www,21端口分配给FTP等 注册端口:2014-49151  分配给用户进程或引用程序 动态/私有端口:49151-65535 需要 ...

  10. C++贪心算法实现部分背包问题

    问题描述: 在部分背包问题中,可以不必拿走整个一件物品,而是可以拿走该物品的任意部分.以此求得在限定背包总重量,从给定的物品中进行选择的情况下的最佳(总价值最高)的选择方案. 细节须知: 分别输出到同 ...