迭代器
- 概述
迭代器是访问集合元素的一种方式。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。 - 可迭代对象
迭代器提供了一个统一的访问集合的接口。只要是实现了__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:
break
print(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 count
for i in count(10): #从10开始无限循环
if i > 20:
break
# pass
else:
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 cycle
count = 0
for item in cycle('XYZ'):
if count > 7:
break
print(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 itertools
list1 = [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 itertools
list1 = [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 ,permutations
list01 = [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