对python中的高效迭代器函数详解


Posted in Python onOctober 18, 2018

python中内置的库中有个itertools,可以满足我们在编程中绝大多数需要迭代的场合,当然也可以自己造轮子,但是有现成的好用的轮子不妨也学习一下,看哪个用的顺手~

首先还是要先import一下:

#import itertools
from itertools import * #最好使用时用上面那个,不过下面的是为了演示比较
  常用的,所以就直接全部导入了

一.无限迭代器:

对python中的高效迭代器函数详解

由于这些都是无限迭代器,因此使用的时候都要设置终止条件,不然会一直运行下去,也就不是我们想要的结果了。

1、count()

可以设置两个参数,第一个参数为起始点,且包含在内,第二个参数为步长,如果不设置第二个参数则默认步长为1

for x in count(10,20):
 if x < 200:
 print x
def count(start=0, step=1):
 # count(10) --> 10 11 12 13 14 ...
 # count(2.5, 0.5) -> 2.5 3.0 3.5 ...
 n = start
 while True:
 yield n
 n += step

2、cycle()

可以设置一个参数,且只接受可以迭代的参数,如列表,元组,字符串。。。,该函数会对可迭代的所有元素进行循环:

for i,x in enumerate(cycle('abcd')):
 if i < 5:
 print x
def cycle(iterable):
 # cycle('ABCD') --> A B C D A B C D A B C D ...
 saved = []
 for element in iterable:
 yield element
 saved.append(element)
 while saved:
 for element in saved:
  yield element

3、repeat()

可以设置两个参数,其中第一个参数要求可迭代,第二个参数为重复次数,第二个参数如不设置则无限循环,一般来说使用时都会设置第二个参数,用来满足预期重复次数后终止:

#注意如果不设置第二个参数notebook运行可能会宕机
for x in repeat(['a','b','c'],10):
 print x

二.有限迭代器

对python中的高效迭代器函数详解

1、chain()

可以接受不定个数个可迭代参数,不要求可迭代参数类型相同,会返回一个列表,这个类似于list的extend,不过不同点是list的extend是对原变量进行改变不返回,而chain则是就地改变并返回:

list(chain(range(4),range(5)))

list(chain(range(4),'abc'))

list(chain(('a','b','c'),'nihao',['shijie','zhongguo']))
def chain(*iterables):
 # chain('ABC', 'DEF') --> A B C D E F
 for it in iterables:
 for element in it:
  yield element

2.compress()

第一个参数为可迭代类型,第二个参数为0和1的集合,两者长度可以不等,

这个暂时不知道可以用在哪里、

list(compress(['a','b','c','d','e'],[0,1,1,1,0,1]))
def compress(data, selectors):
 # compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F
 return (d for d, s in izip(data, selectors) if s)

3.dropwhile()

接受两个参数,第一个参数为一个判断类似于if语句的函数,丢弃满足的项,直到第一个不满足的项出现时停止丢弃,就是

#伪代码大概是这个样子的
if condition:
 drop element
 while not condition:
 stop drop
list(dropwhile(lambda x:x>5,range(10,0,-1)))
def dropwhile(predicate, iterable):
 # dropwhile(lambda x: x<5, [1,4,6,4,1]) --> 6 4 1
 iterable = iter(iterable)
 for x in iterable:
 if not predicate(x):
  yield x
  break
 for x in iterable:
 yield x

4.groupby

对给定可迭代集合(有重复元素)进行分组,返回的是一个元组,元组的第一个为分组的元素,第二个为分组的元素集合,还是看代码吧:

for x,y in groupby(['a','a','b','b','b','b','c','d','e','e']):
 print x
 print list(y)
 print ''

out:
 a
 ['a', 'a']

 b
 ['b', 'b', 'b', 'b']

 c
 ['c']

 d
 ['d']

 e
 ['e', 'e']
class groupby(object):
 # [k for k, g in groupby('AAAABBBCCDAABBB')] --> A B C D A B
 # [list(g) for k, g in groupby('AAAABBBCCD')] --> AAAA BBB CC D
 def __init__(self, iterable, key=None):
 if key is None:
  key = lambda x: x
 self.keyfunc = key
 self.it = iter(iterable)
 self.tgtkey = self.currkey = self.currvalue = object()
 def __iter__(self):
 return self
 def next(self):
 while self.currkey == self.tgtkey:
  self.currvalue = next(self.it) # Exit on StopIteration
  self.currkey = self.keyfunc(self.currvalue)
 self.tgtkey = self.currkey
 return (self.currkey, self._grouper(self.tgtkey))
 def _grouper(self, tgtkey):
 while self.currkey == tgtkey:
  yield self.currvalue
  self.currvalue = next(self.it) # Exit on StopIteration
  self.currkey = self.keyfunc(self.currvalue)

5.ifilter()

这个有点像是filter函数了,不过有点不同,filter返回的是一个完成后的列表,而ifilter则是一个生成器,使用的yield

#这样写只是为了更清楚看到输出,其实这么写就跟filter用法一样了,体现不到ifilter的优越之处了
list(ifilter(lambda x:x%2,range(10)))

6.ifilterfalse()

这个跟ifilter用法很像,只是两个是相反数的关系。

list(ifilterfalse(lambda x:x%2,range(10)))

7.islice()

接受三个参数,可迭代参数,起始切片点,结束切片点,最少给定两个参数,当只有两个参数为默认第二个参数为结束切片点:

In: list(islice(range(10),2,None))
Out: [2, 3, 4, 5, 6, 7, 8, 9]

In: list(islice(range(10),2))
Out: [0, 1]

8.imap()

接受参数个数跟目标函数有关:

#接受两个参数时
list(imap(abs,range(-5,5)))

#接受三个参数时
list(imap(pow,range(-5,5),range(10)))

#接受四个参数时
list(imap(lambda x,y,z:x+y+z,range(10),range(10),range(10)))

9.starmap()

这个是imap的变异,即只接受两个参数,目标函数会作用在第二个参数集合中、

in: list(starmap(pow,[(1,2),(2,3)]))
out: [1, 8]

10.tee()

接受两个参数,第一个参数为可迭代类型,第二个为int,如果第二个不指定则默认为2,即重复两次,有点像是生成器repeat的生成器类型,

这个就有意思了,是双重生成器输出:

for x in list(tee('abcde',3)):
 print list(x)

11.takewhile()

这个有点跟dropwhile()很是想象,一个是丢弃,一个是拿取:

伪代码为:

if condition:
 take this element
 while not condition:
 stop take

eg:

in: list(takewhile(lambda x:x<10,(1,9,10,11,8)))
out: [1, 9]

12.izip()

这个跟imap一样,只不过imap是针对map的生成器类型,而izip是针对zip的:

list(izip('ab','cd'))

13.izip_longest

针对izip只截取最短的,这个是截取最长的,以None来填充空位:

list(izip_longest('a','abcd'))

三、组合迭代器

对python中的高效迭代器函数详解

1.product()

这个有点像是多次使用for循环,两者可以替代。

list(product(range(10),range(10)))

#本质上是这种的生成器模式
L = []
for x in range(10):
 for y in range(10):
 L.append((x,y))

2.permutations()

接受两个参数,第二个参数不设置时输出的没看出来是什么鬼,

第二个参数用来控制生成的元组的元素个数,而输出的元组中最后一个元素是打乱次序的,暂时也不知道可以用在哪

list(permutations(range(10),2))

3.combinations()

用来排列组合,抽样不放回,第二个参数为参与排列组合的个数

list(combinations('abc',2))
def combinations(iterable, r):
 # combinations('ABCD', 2) --> AB AC AD BC BD CD
 # combinations(range(4), 3) --> 012 013 023 123
 pool = tuple(iterable)
 n = len(pool)
 if r > n:
 return
 indices = range(r)
 yield tuple(pool[i] for i in indices)
 while True:
 for i in reversed(range(r)):
  if indices[i] != i + n - r:
  break
 else:
  return
 indices[i] += 1
 for j in range(i+1, r):
  indices[j] = indices[j-1] + 1
 yield tuple(pool[i] for i in indices)
def combinations(iterable, r):
 pool = tuple(iterable)
 n = len(pool)
 for indices in permutations(range(n), r):
 if sorted(indices) == list(indices):
  yield tuple(pool[i] for i in indices)

4.combinations_with_replacement()

与上一个的用法不同的是抽样是放回的

def combinations_with_replacement(iterable, r):
 # combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC
 pool = tuple(iterable)
 n = len(pool)
 if not n and r:
 return
 indices = [0] * r
 yield tuple(pool[i] for i in indices)
 while True:
 for i in reversed(range(r)):
  if indices[i] != n - 1:
  break
 else:
  return
 indices[i:] = [indices[i] + 1] * (r - i)
 yield tuple(pool[i] for i in indices)
def combinations_with_replacement(iterable, r):
 pool = tuple(iterable)
 n = len(pool)
 for indices in product(range(n), repeat=r):
 if sorted(indices) == list(indices):
  yield tuple(pool[i] for i in indices)

以上这篇对python中的高效迭代器函数详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python中根据字符串调用函数的实现方法
Jun 12 Python
Python设计足球联赛赛程表程序的思路与简单实现示例
Jun 28 Python
Python正则替换字符串函数re.sub用法示例
Jan 19 Python
解决出现Incorrect integer value: '' for column 'id' at row 1的问题
Oct 29 Python
python matplotlib实现双Y轴的实例
Feb 12 Python
PyQt弹出式对话框的常用方法及标准按钮类型
Feb 27 Python
Pyinstaller打包.py生成.exe的方法和报错总结
Apr 02 Python
使用Pandas将inf, nan转化成特定的值
Dec 19 Python
在tensorflow中实现去除不足一个batch的数据
Jan 20 Python
基于Python3.6中的OpenCV实现图片色彩空间的转换
Feb 03 Python
Python绘图之柱形图绘制详解
Jul 28 Python
python 算法题——快乐数的多种解法
May 27 Python
对Python中内置异常层次结构详解
Oct 18 #Python
Python运维开发之psutil库的使用详解
Oct 18 #Python
python实现自动登录后台管理系统
Oct 18 #Python
python 对给定可迭代集合统计出现频率,并排序的方法
Oct 18 #Python
python实现简单登陆系统
Oct 18 #Python
Python字典中的键映射多个值的方法(列表或者集合)
Oct 17 #Python
python字典值排序并取出前n个key值的方法
Oct 17 #Python
You might like
PHP 实用代码收集
2010/01/22 PHP
php的一个简单加密解密代码
2014/01/14 PHP
php使用百度翻译api示例分享
2014/01/31 PHP
ThinkPHP模板Switch标签用法示例
2014/06/30 PHP
启用Csrf后POST数据时出现的400错误
2015/07/05 PHP
PHP实现动态执行代码的方法
2016/03/25 PHP
浅谈PHP Cookie处理函数
2016/06/10 PHP
Laravel构建即时应用的一种实现方法详解
2017/08/31 PHP
Laravel框架Request、Response及Session操作示例
2019/05/06 PHP
JavaScript toFixed() 方法
2010/04/15 Javascript
javascript之Partial Application学习
2013/01/10 Javascript
jQuery事件用法实例汇总
2014/08/29 Javascript
node.js中的fs.appendFileSync方法使用说明
2014/12/17 Javascript
微信小程序 网络API 上传、下载详解
2016/11/09 Javascript
BootStrop前端框架入门教程详解
2016/12/25 Javascript
JavaScript实现换肤功能
2017/09/15 Javascript
Django与Vue语法的冲突问题完美解决方法
2017/12/14 Javascript
JavaScript Event Loop相关原理解析
2020/06/10 Javascript
Vue绑定用户接口实现代码示例
2020/11/04 Javascript
[45:14]Optic vs VP 2018国际邀请赛淘汰赛BO3 第二场 8.24
2018/08/25 DOTA
SublimeText 2编译python出错的解决方法(The system cannot find the file specified)
2013/11/27 Python
详解Python中的type和object
2018/08/15 Python
使用python list 查找所有匹配元素的位置实例
2019/06/11 Python
python 返回一个列表中第二大的数方法
2019/07/09 Python
python实现KNN分类算法
2019/10/16 Python
python tornado修改log输出方式
2019/11/18 Python
如何在Django中使用聚合的实现示例
2020/03/23 Python
CSS3为背景图设置遮罩并解决遮罩样式继承问题
2020/06/22 HTML / CSS
HTML5 Canvas绘制文本及图片的基础教程
2016/03/14 HTML / CSS
突袭HTML5之Javascript API扩展3—本地存储全新体验
2013/01/31 HTML / CSS
18-35岁旅游团的全球领导者:Contiki
2017/02/08 全球购物
员工自我鉴定范文
2013/10/06 职场文书
入党团支部推荐意见
2015/06/02 职场文书
2016年七夕爱情寄语
2015/12/04 职场文书
全面盘点MySQL中的那些重要日志文件
2021/11/27 MySQL
通过T-SQL语句创建游标与实现数据库加解密功能
2022/03/16 SQL Server