一、迭代器
1、定义
迭代器是一个可以记住遍历的位置的对象。
迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
2、方法
迭代器有两个基本的方法:iter() 和 next()。
iter() 用来创建迭代器
next()用于访问迭代器的下一个元素
3、创建
字符串,列表或元组对象都可用于创建迭代器
list=[1,2,3,4]
it = iter(list) # iter方法创建迭代器对象
print (next(it)) # 输出迭代器的下一个元素
# 1
print (next(it))
# 2
4、遍历
迭代器对象可以使用常规for语句进行遍历
list=[1,2,3,4]
it = iter(list) # 创建迭代器对象
for x in it:
print (x, end=" ")
# 1 2 3 4
5、异常
StopIteration用于标识迭代的完成。在next()遍历完所有元素后会引起次异常。
a = [i for i in range(3)] #列表推导式
it = iter(a)
print(next(it))
print(next(it))
print(next(it))
print(next(it))
二、生成器
1、定义
使用了 yield 的函数被称为生成器(generator)
2、作用
通过列表生成式,我们可以直接创建一个列表。
L = [x * x for x in range(10)]
print(L)
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。
生成器不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。
3、创建
要创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator:
g = (x * x for x in range(10))
print(g)
<generator object <genexpr> at 0x1022ef630>
在上面的例子中:(x * x for x in range(10))是生成器,g是迭代器。
生成器是个函数(一个返回迭代器的函数)!迭代器是个对象!
4、遍历
既让生成器(返回的结果)也是迭代器,直接打印他是个对象地址,但他的元素是可以遍历的,且不需要关心StopIteration的错误:
for i in g:
print(i)
或者可以通过__next__()从生成器中取值
g = (x * x for x in range(10))
print(g.__next__())
print(g.__next__())
print(g.__next__())
print(g.__next__())
5、使用yield
跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。
在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。
这里的yield 相当于return
import sys
def fibonacci(n): # 生成器函数 - 斐波那契
a, b, counter = 0, 1, 0
while True:
if (counter > n):
return
yield a
a, b = b, a + b
counter += 1
f = fibonacci(10) # f 是一个迭代器,由生成器返回生成
此时,可以使用迭代器next()方法遍历,这种方法实际很少用到
while True:
try:
print (next(f), end=" ")
except StopIteration:
sys.exit()
也可以使用for循环遍历
for i in f:
print(i)
平时常用到的迭代器:range。
生成器占用内存小,在使用的时候取值,降低CPU和内存空间,提高效率。符合“即用即取”的思想。
6、补充:itertools
itertools中的额函数大多数是返回各种迭代器对象,其中很多函数的作用我们平时要写很多代码才能达到,而在运行效率上反而更低,毕竟人家是系统库。
1、itertools.accumulate
accumulate简单来说就是累加
from itertools import accumulate
x = accumulate(range(10))
print(list(x))
# [0, 1, 3, 6, 10, 15, 21, 28, 36, 45]
2、itertools.product
product 用于求多个可迭代对象的组合,它跟嵌套的 for 循环等价。
它的一般使用形式如下:
product(iter1, iter2, … iterN, [repeat=1])
from itertools import product
for item in product('abcd', 'xyz'):
print(item,end = " ")
# ('a', 'x') ('a', 'y') ('a', 'z') ('b', 'x') ('b', 'y') ('b', 'z') ('c', 'x') ('c', 'y') ('c', 'z') ('d', 'x') ('d', 'y') ('d', 'z')
3、itertools.permutations
permutations产生指定数目元素的所有排列(顺序有关)
它的一般使用形式如下:
permutations(iterable[, r])
其中,r 指定生成排列的元素的长度,如果不指定,则默认为可迭代对象的元素长度。
from itertools import permutations
x = permutations((1,2,3))
print(list(x))
# [(1, 2, 3), (1, 3, 2), (2, 1, 3), (2, 3, 1), (3, 1, 2), (3, 2, 1)]
list(permutations('ABC', 2))
# [('A', 'B'), ('A', 'C'), ('B', 'A'), ('B', 'C'), ('C', 'A'), ('C', 'B')]
4、itertools.combinations
combinations 用于求序列的组合(顺序无关)
它的使用形式如下:
combinations(iterable, r)
list(combinations('ABC', 2))
# 结果为:[('A', 'B'), ('A', 'C'), ('B', 'C')]
无限迭代器
itertools 模块提供了三个函数(事实上,它们是类)用于生成一个无限序列迭代器:
1、count(firstval=0, step=1)
创建一个从 firstval (默认值为 0) 开始,以 step (默认值为 1) 为步长的的无限整数迭代器
2、cycle(iterable)
对 iterable 中的元素反复执行循环,返回迭代器
3、repeat(object [,times]
反复生成 object,如果给定 times,则重复次数为 times,否则为无限