###迭代器(iterator)

迭代器的一般介绍

  • 迭代是Python最强大的功能之一,是访问集合元素的一种方式。
  • 迭代器是一个可以记住遍历的位置的对象。
  • 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
  • 迭代器有两个基本的方法:iter()next()
  • 字符串,列表或元组对象都可用于创建迭代器

简单的问题:小明想知道列表[0, 1, 2, 3]中每个数字的平方数

  1. 直接列出列表内数字的平方和,让小明自己**《看》**。

    1
    2
    
    list1 = [0, 1, 2, 3]
    list2 = [x**2 for x in list1]
    

    缺点:占用的内存会随着参数 列表 的增大而增大,如果要控制内存占用,最好不要用 List。

  2. 逐个告诉小明,让小明自己**《记住》**。

    • step1: 逐个获取列表中的数字
    • step2: x**2(方法)
    • step3: 结果
    1
    2
    3
    
    list1 = [0, 1, 2, 3]
    for i in list1:
        print(i**2)
    

迭代思想

在上述例子中,第2个解答的思想如下:

  1. 要有一个可遍历对象,如:[0, 1, 2, 3]。
  2. 从列表的第一个元素开始逐个访问,直到所有元素被访问完结束。
  3. 访问过程是一直前进没有后退。
  4. 对获取到的数字,进行某种操作给出结果,如:求平方。

迭代器

  • 迭代器就是一个 容器 。在python中可以使用 iter()方法 将可遍历对象(列表、字典、字符串、元组),也称之为可迭代对象,转换成迭代器。
  • 对迭代器的每一次操作都能 获取到下个元素 的信息。在python中为 next()方法
  • 当迭代完成时,结束迭代。在python中 StopIteration异常 用于完成指定迭代次数时,结束迭代,防止无限循环。

例子1:

1
2
3
4
5
6
7
>>> list1 = [0,1,2,3]
>>> it = iter(list)    # 创建迭代器对象
>>> print (next(it))   # 输出迭代器的下一个元素
0
>>> print (next(it))
1
>>>

例子2:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
list2 = [0, 1, 2, 3]
it = iter(num)
while True:
    try:
        print(next(it))
    except StopIteration:
        break
        
##输出
0
1
2
3

例子3:再次看 小明想知道列表[0, 1, 2, 3]中每个数字的平方数

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
list2 = [0, 1, 2, 3]
it = iter(num)
while True:
    try:
        print(next(it)**2)
    except StopIteration:
        break
        
##输出
0
1
4
9

对比前面的for循环,此代码的复用率更高。

###生成器(generator)

现在,我们已经了解迭代器原理:将可迭代对象转化成一个迭代器(iter()方法),然后逐个获取里面的元素(next()方法)。

**Q:**如果没有现成的可迭代对象(列表、字典、字符串、元组),程序每执行一次,我也想暂停并保持当前所有的运行信息,该怎么办?

A: 既然没有现成的迭代对象,那就 生成(generate) 一个迭代器不就好了。在python中 yield()方法 可以实现 暂停并保持当前所有的运行信息

使用yield实现前N个斐波那契数列的输出

**斐波那契额数列定义:**这个数列从第3项开始,每一项都等于前两项之和 $F_n=F_{n-1}+F_{n-2}$。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
def fab(max): 
    n, a, b = 0, 0, 1 
    while n < max: 
        yield b      # 使用 yield
        # print b 
        a, b = b, a + b #递推公式
        n = n + 1
f = fab(5)

while True:
    try:
        print(next(f),end=',')
    except StopIteration:
        break

##输出
1,1,2,3,5,

分析:

  • 函数的功能:fab() 函数有一个初始的输入值(n, a, b = 0, 0, 1 ),和相应的函数功能(a, b = b, a + b #递推公式)
  • 使用 yield()方法 暂停并保持当前所有的运行信息
  • **包含 yield()方法 的函数 fab() 变成一个生成器。可以使用 next() 方法。**生成器可以看成一个特殊的迭代器,因为生成器是,一边生成数据,一边输出。

简单的python生成器:()

要创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator:

1
2
3
4
5
6
7
8
9
##列表推导式
L = [x * x for x in range(10)]
L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

###创建一个生成器
g = (x * x for x in range(10))
g
<generator object <genexpr> at 0x1022ef630>

####分析 g = (x * x for x in range(10))

  • x*x : 相当于 函数功能
  • for x in range(10) : 相当于 while 和 x = x+1。逐个取值
  • 外面的() : 实现了 yield()方法,暂停并保持当前所有的运行信息。

总结

  1. 迭代器 就是一种特殊的数据容器,通过next()方法依次获取元素。
  2. 对 可迭代对象 使用 iter() 方法,可以变成迭代器。
  3. 生成器 可以看成特殊的 迭代器,一边生成数据一边记录当前数据。
  4. 在 Python 中,使用了 yield 的函数被称为生成器(generator)。

参考: