Python迭代器:告别循环嵌套,走向优雅编程

发布时间:2023年12月23日

刷完这60个标准库模块,成为Python骨灰级玩家

itertools是python专为高效循环而创建的一组迭代器函数,用过的都说好。

无穷迭代器

itertools中包有三个无穷迭代器,分别是count, cyclerepeat,由于迭代器这种东西很难描述,所以直接看案例。唯一需要注意一点就是,千万别对无穷迭代器用list


count

>>> import itertools as it
>>> x = it.count(0,2)   #两个参量分别是初始值和步长,
>>> next(x)
0
>>> for i in range(3): print(next(x),end=' ')
...
2 4 6
>>> x = it.count(3)     #步长为可选参量,默认为1
>>> for i in range(3) : print(next(x),end=' ')
...
3 4 5
>>> for _ in range(10): print(next(x), end=' ')
...
6 7 8 9 10 11 12 13 14 15

其中,x的两个参量分别是初始值和步长,步长为可选参量,默认为1。


cycle

cycle的参数可以是列表元组或者是字符串。

>>> c = it.cycle([1,2,3])   #对1,2,3进行无穷的循环
>>> next(c)
1
>>> for i in range(10): print(next(c),end=' ')
...
2 3 1 2 3 1 2 3 1 2
>>> c = it.cycle("love")    #其参数也可以为字符串
>>> for i in range(10): print(next(c), end=' ')
...
l o v e l o v e l o

repeat

一般来说,repeat有两个输入参数,一个是循环内容,第二个参数是循环次数。如果省略第二个参数,就表示无穷循环。

>>> r = it.repeat(10,3) #对10循环3次
>>> list(r)
[10, 10, 10]
>>> r = it.repeat(10)   #如果只有一个参数,则无穷循环
>>> for i in range(10): print(next(r), end=' ')
...
10 10 10 10 10 10 10 10 10 10
>>> r = it.repeat([1,2],3)
>>> list(r)
[[1, 2], [1, 2], [1, 2]]

迭代运算器

这类迭代器可以找到与之相似的python表达式,区别在于效率,毕竟itertools是在底层实现的。

下表中,左侧为迭代器表达式,右侧为将这个迭代器转换为list之后的形式,默认from itertools import *

accumulate(lst,func)累加求和
chain(as,bs,…)列表连加器
compress(d,s)根据s的真值取d
filterfalse(func,lst)lst中func为假的元素
dropwhile(func,lst)lst中,自func为假之后的元素
takewhile(func,lst)lst中,自func为假之前的元素
islice(lst,[s,]e,[,step])索引

解释很无力,具体还是要看代码:

用于“积分”

>>> from itertools import *
>>> from math import *
>>> lst = list(range(4,-4,-1))
>>> lst
[4, 3, 2, 1, 0, -1, -2, -3]
## accumulate  自左向右执行函数
>>> list(accumulate(lst))       #累加求和
[4, 7, 9, 10, 10, 9, 7, 4]
>>> list(accumulate(lst,max))   #自左向右取最大值
[4, 4, 4, 4, 4, 4, 4, 4]
>>> list(accumulate(lst,min))   #自左向右取最小值
[4, 3, 2, 1, 0, -1, -2, -3]
## chain,相当于[*lst,*lst]
>>> list(chain(lst,lst))
[4, 3, 2, 1, 0, -1, -2, -3, 4, 3, 2, 1, 0, -1, -2, -3]
>>> [*lst,*lst]
[4, 3, 2, 1, 0, -1, -2, -3, 4, 3, 2, 1, 0, -1, -2, -3]

用于筛选

## compress
>>> flags = [i>0 for i in lst]
>>> flags
[True, True, True, True, False, False, False, False]
>>> list(compress(lst,flags))
[4, 3, 2, 1]
## filterfalse
>>> isNeg = lambda x : x<0
>>> list(filterfalse(isNeg,lst))
[4, 3, 2, 1, 0]
## dropwhile
>>> isOdd = lambda x : not x%2  #如果为偶数则返回True
>>> list(dropwhile(isOdd,lst))  #3是奇数,从而返回自3之后的值
[3, 2, 1, 0, -1, -2, -3]
## takewhile
>>> isPos = lambda x : x>0
>>> list(takewhile(isPos,lst))  #输出isPos为假之前的内容
[4, 3, 2, 1]

用于切片与组合

## islice
>>> list(islice(lst,3))
[4, 3, 2]   # 等于lst[:3]
>>> list(islice(lst,1,3))
[3, 2]      # 等于lst[1:3]
>>> list(islice(lst,0,6,2))
[4, 2, 0]   # 等于lst[0:6:2]
## pairwise(lst),相当于zip(lst[:-1],lst[1:])
>>> list(pairwise(lst))
[(4, 3), (3, 2), (2, 1), (1, 0), (0, -1), (-1, -2), (-2, -3)]
>>> list(zip(lst[:-1],lst[1:]))
[(4, 3), (3, 2), (2, 1), (1, 0), (0, -1), (-1, -2), (-2, -3)]
## zip_longest,按照最长的序列进行zip,不足补充fillvalue
>>> list(zip_longest(lst[:3],lst[:2],fillvalue=0))
[(4, 4), (3, 3), (2, 0)]

其中,pairwise(lst),相当于zip(lst[:-1],lst[1:]);zip_longest,按照最长的序列进行zip,不足补充fillvalue。

排列组合迭代器

product是笛卡尔积,换言之就是两列参数中一对一的组合。通过product,可以替代嵌套的for循环。

permutations 输入序列的多次组合,每个组合中不得有重复元素;combinations 在permutations的基础上,要求元组有序;combinations_with_replacement 则是元素可重复的combination

## product 笛卡尔积
>>> lst = list(range(4))
>>> lst
[0, 1, 2, 3]
>>> list(product(lst,lst))
[(0, 0), (0, 1), (0, 2), (0, 3), (1, 0), (1, 1), (1, 2), (1, 3), (2, 0), (2, 1), (2, 2), (2, 3), (3, 0), (3, 1), (3, 2), (3, 3)]
## product 可以用来替代嵌套的for循环
>>> list(product(lst,lst))
[(0, 0), (0, 1), (0, 2), (0, 3), (1, 0), (1, 1), (1, 2), (1, 3), (2, 0), (2, 1), (2, 2), (2, 3), (3, 0), (3, 1), (3, 2), (3, 3)]
>>> for i,j in product(lst,lst):
...   print(i,j,end=';')
...
0 0;0 1;0 2;0 3;1 0;1 1;1 2;1 3;2 0;2 1;2 2;2 3;3 0;3 1;3 2;3 3;

>>> list(permutations(lst,2))
[(0, 1), (0, 2), (0, 3), (1, 0), (1, 2), (1, 3), (2, 0), (2, 1), (2, 3), (3, 0), (3, 1), (3, 2)]
# combinations 在permutations的基础上,要求元组有序
>>> list(combinations(lst,2))
[(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3)]
## combinations_with_replacement 元素可重复的combination
>>> list(combinations_with_replacement(lst,2))
[(0, 0), (0, 1), (0, 2), (0, 3), (1, 1), (1, 2), (1, 3), (2, 2), (2, 3), (3, 3)]

其他

## groupby 返回迭代地址
>>> for k, g in groupby(lst):
...   print(k,list(g))
...
0 [0]   #其中k为lst中的值;g为该值生成的迭代器
1 [1]   #通过list将g这个迭代器又转化为了list
2 [2]
3 [3]
## starmap  输入为函数和列表(可迭代变量),要求列表的每个元素都是列表,然后取出列表中的值执行
>>> list(starmap(lambda x:-x, [[x] for x in lst]))
[0, -1, -2, -3]
>>> list(starmap(lambda x,y:x+y, list(product(lst,lst))))
[0, 1, 2, 3, 1, 2, 3, 4, 2, 3, 4, 5, 3, 4, 5, 6]
文章来源:https://blog.csdn.net/m0_37816922/article/details/121181511
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。