美文网首页Python入门系列
Python入门系列(五)——迭代

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

作者: RabbitMask | 来源:发表于2019-01-17 14:25 被阅读35次

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

    一、迭代器

    我们提一下先提迭代的概念:迭代即为循环遍历,任何遍历的过程都是可以称作迭代。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行代码,然而生成器却只用了三行代码,这就是我们为什么说生成器是使用简单的方式进行迭代。

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

    相关文章

      网友评论

        本文标题:Python入门系列(五)——迭代

        本文链接:https://www.haomeiwen.com/subject/thrmdqtx.html