• python的迭代器和生成器


    本文将简要介绍python中迭代器和生成器的区别与联系,以下内容基于python2.7环境

    1. 可迭代对象与迭代器

     

    1.1 可迭代对象

      可迭代对象需要满足的条件:实现了 __iter__ 方法,该方法返回一个迭代器对象,可以使用for...in...循环进行取值。

      例如:list, tuple, dict, str, set 等等。

     

    1.2 迭代器

      迭代器条件:实现了 __iter__ 和 next 方法。

      如果调用了next方法,容器没有值可以返回,则会抛出一个StopIteration异常。

      next方法的使用有两种方式:i.next() 和 next(i)。

     

    判断方法

    from collections import Iterable,Iterator
    print isinstance(["S","u","g","a","r"], Iterable)
    print isinstance(["S","u","g","a","r"], Iterator)
    print isinstance(iter(["S","u","g","a","r"]), Iterator)  # 对于python内置的可迭代对象,可以使用函数iter()获取相应的迭代器
    运行结果: True False True

    代码举例1

    class Test():
        def __init__(self,data=1):
            self.data = data
        def __iter__(self):
            return self
        def next(self):
            if self.data > 5:
                raise StopIteration
            else:
                self.data+=1
                return self.data
    t = Test(3)
    from collections import Iterator
    print isinstance(t, Iterator)
    for i in t:
        print i
    运行结果:
    True
    4
    5
    6

    代码举例2(斐波那契数列)

    class Fibonacci_sequence(object):
        def __init__(self):
            self.prev = 0
            self.cur = 1
        def __iter__(self):
            return self
        def next(self):
            value = self.cur
            self.prev,self.cur = self.cur,self.prev+self.cur
            return value
    fib = Fibonacci_sequence()
    print fib.next(),next(fib),fib.next(),next(fib),fib.next(),fib.next()
    from collections import Iterator
    print isinstance(fib, Iterator)
    运行结果:
    1 1 2 3 5 8
    True

    补充

    #itertools函数返回的都是迭代器对象
    
    from itertools import count,cycle
    from collections import Iterator
    
    counter = count(start=1, step=3)
    print isinstance(counter,Iterator)
    print next(counter)
    print counter.next()
    print next(counter)
    print counter.next()
    运行结果:
    True
    1
    4
    7
    10
    
    colors = cycle(["red","green","blue"])
    print colors.next(),colors.next(),colors.next(),colors.next(),colors.next(),colors.next()
    运行结果:
    red green blue red green blue

    小结

    迭代器一定是可迭代对象,可迭代对象不一定是迭代器!
    迭代器不会一次性把所有元素加载到内存,而是需要的时候才生成返回结果!
    iter()和__iter__不同,iter()是直接调用了对象的__iter__方法,并且把这个方法的返回值作为自己的返回值。

    在for..in...循环中,比如 for i in list,会先调用iter(list)得到可迭代对象list的迭代器,每次循环再调用迭代器的next()方法获取值。

    2. 生成器

    生成器是一种特殊的迭代器(更加优雅),它不需要像类一样写__iter__和next方法,只需要一个yield关键字即可,生成器一定是迭代器

    2.1 生成器函数

    代码举例1

    def func():
        a = 0
        while True:
            yield a
            a += 1
    f = func()  # f就是一个生成器,通过调用f的next方法取值
    print f.next(),next(f),next(f),next(f),next(f)
    运行结果:
    0 1 2 3 4

    代码举例2(斐波那契数列)

    def fibonacci_sequence():
        prev,cur = 0,1
        while True:
            yield cur
            prev,cur = cur,prev+cur
    fib = fibonacci_sequence()  # fib是一个生成器,通过调用next方法取值
    print fib.next(),fib.next(),fib.next(),fib.next(),fib.next(),fib.next(),fib.next()
    from collections import Iterable,Iterator
    print isinstance(fib, Iterable)
    print isinstance(fib, Iterator)
    运行结果:
    1 1 2 3 5 8 13
    True
    True

    2.2 生成器表达式

    代码举例

    generator = (i for i in range(10))    # 注意使用的是小括号而不是中括号
    from collections import Iterable,Iterator
    print isinstance(generator, Iterable)
    print isinstance(generator, Iterator)
    运行结果:
    True
    True
    记住要仰望星空,不要低头看脚下。无论生活如何艰难,请保持一颗好奇心。你总会找到自己的路和属于你的成功。
  • 相关阅读:
    javascript初识
    css定位及叠放次序
    css精灵图
    css元素的显示及隐藏、文字隐藏
    css浮动
    盒子模型的边框、内边距、外边距、阴影
    css背景
    css中的显示与隐藏
    css定位
    css的布局与版心布局
  • 原文地址:https://www.cnblogs.com/samtech/p/9689555.html
Copyright © 2020-2023  润新知