Python入门系列(五)——迭代

目录:
一、迭代器
二、生成器

一、迭代器

我们提一下先提迭代的概念:迭代即为循环遍历,任何遍历的过程都是可以称作迭代。Python中序列、集合、字典、文件和生成器等都是可迭代的,任何可迭代对象都可以作用于for循环。
首先我们来借助最基本的两个内置函数iter() 和 next()来完成一个简单的迭代器。

a=range(3)
it=iter(a)                  # 创建迭代器对象

while 1:
        print (next(it))    #输出迭代器的下一个元素,迭代器对象从第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。

#输出
0
1
2
Traceback (most recent call last):
    print (next(it))     
StopIteration

我们可以看到触发了StopIteration异常,StopIteration 异常用于标识迭代的完成,防止出现无限循环的情况,所以我们做如下改写:

import sys

a=range(3)
it=iter(a)    # 创建迭代器对象

while 1:
    try:
      print (next(it))      #输出迭代器的下一个元素,迭代器对象从第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
    except StopIteration:   #我们设置在完成循环次后捕获 StopIteration 异常来结束迭代。
        sys.exit()

#输出
0
1
2

但,for循环却自带异常处理机制:

a=range(3)
it=iter(a)    # 创建迭代器对象

for i in  a:
      print (next(it))  

#输出
0
1
2
类中迭代器的使用

然后我们来拓展一下关于类中的迭代器,之前大家应该也已经留意到了,类中是内置了迭代器的专有方法的。

class Numbers:
    def __init__(self,n):       #构造函数,获取参数范围,即打印0到几
        self.n=n
    def __iter__(self):         #实例化对象的迭代器创建方法
        self.a=0
        return self
    def __next__(self):         #返回迭代器对象下一个元素的方法
        if self.a <=self.n:
            res=self.a
            self.a+=1
            return res
        else:
            raise StopIteration #raise用以引发异常。一旦执行了raise语句,raise后面的语句将不能执行


num=Numbers(3)                  #实例化对象num
it=iter(num)                    #创建实例num的迭代器对象it

print(next(it))                 #输出迭代器对象it的下一个元素
print(next(it))
print(next(it))
print(next(it))

#输出
0
1
2
3

当然,我们最后的输出完全可以使用for循环将迭代器中的内容读出来,输出相同。

# print(next(it))                 #输出迭代器对象it的下一个元素
# print(next(it))
# print(next(it))
# print(next(it))

for i in it:
    print(i)

或者使用while循环,不过依然要添加异常处理:

while 1:
    try:
        print(next(it))
    except StopIteration: #使用try-except语句捕捉异常
        pass              #啥也不想干,占个位

二、生成器

而生成器是一个简单的方式来完成迭代,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。

觉得上面的概念太抽象?我们借助实例来解释~几乎所有相关教程都在扯著名的斐波那契数列,我们就不!

说起生成器的创建,常用两种方法,一种是改写列表生成式,一种是使用yield。

列表生成式

列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式,其实我们之前就有在使用了。

a=[x for x in range(10)]
print(a)

#输出
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

顾名思义,它生成了一个列表,那么如何改写为生成器呢?

a=(x for x in range(10))
print(type(a))

#输出
<class 'generator'>

我们可以看到,当前类型已经变为’generator’,即生成器类型。改写方法就是将[ ]替换为( )
接下来我们尝试使用一下:

a=(x for x in range(10))

while 1:
    try:
        print(next(a))
    except:
        pass

#输出
0
1
2
3
4
5
6
7
8
9
yield

在python中,任何使用了 yield 的函数都被称为生成器(generator)或生成器函数。

def numbers(n):             #创建生成器函数,这已经不是一个普通函数啦
    for i in range(n):
        yield i             #在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。

num=numbers(3)              #调用生成器函数,返回的是一个迭代器对象,即num。

for i in  num:              #上个例子用的while,这次我们用for
    print(i)

#输出
0
1
2

这里往上翻一下,你会发现它与类中迭代器的使用中的例子功能是一致的,但那里用了近20行代码,然而生成器却只用了三行代码,这就是我们为什么说生成器是使用简单的方式进行迭代。

说到底,生成器就是一种特殊的迭代器,这也就是为什么这一章节题目如此简单:《迭代》。

    原文作者:RabbitMask
    原文地址: https://www.jianshu.com/p/c3187f5be3e0
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞