迭代器
-
概述
迭代器是访问集合元素的一种方式。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
-
可迭代对象
迭代器提供了一个统一的访问集合的接口。只要是实现了__iter__()或 getitem()方法的对象,就可以使用迭代器进行访问。
序列:字符串、列表、元组
非序列:字典、文件
自定义类:用户自定义的类实现了__iter__()或__getitem__()方法的对象
迭代字典
d = {'a': 1, 'b': 2, 'c': 3}for k in d:print(k)for k in d.keys():print(k)for v in d.values():print(v)for (k,v) in d.items():print(k,v)
-
迭代基础
f1=open('data.txt')# for line in f1.readlines(): #把所有行读入内存,遇到大文件效率差# print(line)# for line in f1:# print(line)# 文件对象就是自己的迭代器print(f1.__next__())print(f1.__next__())# 为了手动支持迭代,python3.0提供了一个next()方法,他会自动调用对象的_next_()print(next(f1))
-
iter() 和 next()
字符串/数组本身没有迭代对象
s='hello'iter01=iter(s)print(next(iter01))print(next(iter01))arr=[1,2,3,4]E=iter(arr)# print(E.__next__())# print(next(E))while True:try:X=E.__next__()except StopIteration:breakprint(X)
字典对象有一个迭代器,每次返回字典的key
params={'name':'tom','age':12}for key in params:...#所以不要下面的写法for key in params.keys():...
-
range()
range()支持多个迭代器,而其他内置函数不支持
arr=list(range(20))print(arr)R=iter(range(100))print(next(R))print(next(R))print(next(R))
-
map() zip() filter()
和range()不同,以上三个函数都是自己的迭代器M=map(abs,[2,-3,-1,3])print(next(M))
itertools
itertools 是python的迭代器模块,itertools提供的工具相当高效且节省内存
###无限迭代的迭代器
-
count(初值=0, 步长=1)
无限迭代
from itertools import countfor i in count(10): #从10开始无限循环if i > 20:break# passelse:print(i)
-
slice(count(10), 5)
从 10 开始,输出 5 个元素后结束。islice 的第二个参数控制何时停止迭代。但其含义并不是”达到数字 5 时停止“,而是”当迭代了 5 次之后停止“。
from itertools import count,islice for i in islice(count(10), 5):print(i)
-
cycle()
from itertools import cyclecount = 0for item in cycle('XYZ'):if count > 7:breakprint(item)count += 1
这里我们创建了一个 for 循环,使其在三个字母 XYZ 间无限循环。当然,我们并不真地想要永远循环下去,所以我们添加了一个简单的计数器来跳出循环。
###可终止迭代器
-
accumulate(可迭代对象[, 函数])
accumulate 迭代器将返回累计求和结果,或者传入两个参数的话,由传入的函数累积计算的结果。默认设定为相加,我们赶快试一试吧:
>> from itertools import accumulate>>> list(accumulate(range(10)))[0, 1, 3, 6, 10, 15, 21, 28, 36, 45]
这里,我们 导入了 accumulate,然后传入 10 个数字,0-9。迭代器将传入数字依次累加,所以第一个是 0 ,第二个是 0+1, 第三个是 1+2,如此下去。现在我们导入 operator 模块,然后添加进去:
>>> import operator>>> list(accumulate(range(1, 5), operator.mul))[1, 2, 6, 24]
这里我们传入了数字 1-4 到 accumulate 迭代器中。我们还传入了一个函数:operator.mul,这个函数将接收的参数相乘。所以每一次迭代,迭代器将以乘法代替除法(1×1=1, 1×2=2, 2×3=6, 以此类推)。
accumulate 的文档中给出了其他一些有趣的例子,例如贷款分期偿还,混沌递推关系等。这绝对值得你花时间去看一看。 -
combinations(iterable, r)
方法可以创建一个迭代器,返回iterable中所有长度为r的子序列,返回的子序列中的项按输入iterable中的顺序排序。
import itertoolslist1 = [1, 3, 4, 5]list2 = list(itertools.combinations(list1, 2))print(list2)返回结果:[(1, 3), (1, 4), (1, 5), (3, 4), (3, 5), (4, 5)]
实现一组数据的所有排列组合
import itertoolslist1 = [1, 3, 4, 5]list2 = []for i in range(1, len(list1)+1):iter1 = itertools.combinations(list1, i)list2.append(list(iter1))print(list2)返回结果:[[(1,), (3,), (4,), (5,)], [(1, 3), (1, 4), (1, 5), (3, 4), (3, 5), (4, 5)], [(1, 3, 4), (1, 3, 5), (1, 4, 5), (3, 4, 5)], [(1, 3, 4, 5)]]
#排列组合
-
Python内置的排列组合函数有四个:
product 笛卡尔积 (有放回抽样排列)
permutations 排列 (不放回抽样排列)
combinations 组合,没有重复 (不放回抽样组合)
combinations_with_replacement 组合,有重复 (有放回抽样组合)
permutations 在数学中可以理解为:A(3|4)=4*3*2=24
combinations 在数学中可以理解为:C(3|4)=C(1|4)=4
例题如下:
from itertools import combinations ,permutationslist01 = [1, 2, 3, 5,]a = list(combinations(list01,3))b = list(permutations(list01,3))print(a) #[(1, 2, 3), (1, 2, 5), (1, 3, 5), (2, 3, 5)]print(b) #[(1, 2, 3), (1, 2, 5), (1, 3, 2), (1, 3, 5), (1, 5, 2), (1, 5, 3), (2, 1, 3), (2, 1, 5), (2, 3, 1), (2, 3, 5), (2, 5, 1), (2, 5, 3), (3, 1, 2), (3, 1, 5), (3, 2, 1), (3, 2, 5), (3, 5, 1), (3, 5, 2), (5, 1, 2), (5, 1, 3), (5, 2, 1), (5, 2, 3), (5, 3, 1), (5, 3, 2)]print(len(b)) #24