迭代器

  1. 概述
    迭代器是访问集合元素的一种方式。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
  2. 可迭代对象
    迭代器提供了一个统一的访问集合的接口。只要是实现了__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)
  1. 迭代基础
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))
  1. 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():
     ...
  1. range()
    range()支持多个迭代器,而其他内置函数不支持
arr=list(range(20))
 print(arr)
 
 R=iter(range(100))
 
 print(next(R))
 print(next(R))
 print(next(R))
  1. map() zip() filter()
    和range()不同,以上三个函数都是自己的迭代器
M=map(abs,[2,-3,-1,3])
 print(next(M))

itertools

itertools 是python的迭代器模块,itertools提供的工具相当高效且节省内存

###无限迭代的迭代器

  1. count(初值=0, 步长=1)
    无限迭代
from itertools import count
 for i in count(10): #从10开始无限循环
     if i > 20:
         break
         # pass
     else:
         print(i)
  1. slice(count(10), 5)
    从 10 开始,输出 5 个元素后结束。islice 的第二个参数控制何时停止迭代。但其含义并不是”达到数字 5 时停止“,而是”当迭代了 5 次之后停止“。
from itertools import count,islice
for i in islice(count(10), 5):
    
    print(i)
  1. cycle()
from itertools import cycle

 count = 0
 for item in cycle('XYZ'):
     if count > 7:
         break
     print(item)
     count += 1

这里我们创建了一个 for 循环,使其在三个字母 XYZ 间无限循环。当然,我们并不真地想要永远循环下去,所以我们添加了一个简单的计数器来跳出循环。

###可终止迭代器

  1. 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 的文档中给出了其他一些有趣的例子,例如贷款分期偿还,混沌递推关系等。这绝对值得你花时间去看一看。

  1. 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)]]

#排列组合

  1. 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