美文网首页
(5) python 迭代器和生成器

(5) python 迭代器和生成器

作者: 小黄不头秃 | 来源:发表于2022-10-20 00:22 被阅读0次

    (一)迭代器

    迭代器是一种对象,该对象包含值的可计数数字。
    迭代器是可迭代的对象,这意味着您可以遍历所有值。

    从技术上讲,在 Python 中,迭代器是实现迭代器协议的对象,它包含方法 iter() 和 next()。

    列表、元组、字典和集合都是可迭代的对象。它们是可迭代的容器,您可以从中获取迭代器(Iterator)。

    所有这些对象都有用于获取迭代器的 iter() 方法:
    也可以使用for循环,循环遍历可迭代对象。
    当迭代器已经将可迭代对象里面的数据都读取完了,你再使用next方法就会报错StopIteration。

    如果一个对象实现了__iter__方法,那么它就是一个可迭代对象。
    如果一个对象实现了__iter____next__方法,那么它就是一个迭代器。

    list1 = [1,2,3,4,5]
    str1 = "abcdefg"
    it1 = iter(list1)
    it2 = iter(str1)
    print(next(it1)) # 1
    print(next(it2)) # a
    
    for i in it1:
        print(i) # 2 3 4 5
    
    print(next(it1)) # StopIteration:
    
    # 自定义迭代器
    class MyNumber:
        def __init__(self,start=0, value=0, step=1) -> None:
            if start > value:
                raise Exception("开始值不能大于结束值!")
            self.value = value 
            self.step = step
            self.start = start
    
        def __iter__(self):
            self.index  =  self.start
            self.x = None
            return self # 必须要返回迭代器对象本身
    
        def __next__(self):
            if self.index < self.value:
                self.x = self.index
                self.index += self.step
                return self.x
            else:
                # print("结束了")
                raise StopIteration
    
    for i in MyNumber(-5,5,2): # 创建了一个类似range类的MyNumber类
        print(i)
    
    # 等同于
    for i in range(-5,5,2): # 左闭右开[-5, 5)
        print(i)
    

    所以根据上面的代码我们可以得出for循环的工作流程。

    1. 调用该对象的iter方法获取迭代器
    2. 调用next方法,获取迭代值
    3. 捕获StopIteration异常,结束循环
    4. 执行for循环里的代码

    生成器

    其实生成器也是一种迭代器,但是它是一种特殊的迭代器。他的功能是,我们每调用一次就会返回一个值,这个值是调用的时候生成的,并不是提前准备好的。

    (1)二者区别

    1.迭代器是访问容器的一种方式,也就是说容器已经出现。我们是从已有元素拓印出一份副本,只为我们此次迭代使用。而生成器则是,而生成器则是自己生成元素的。也就是前者是从有到有的复制,而后者则是从无到有的生成。以 list 容器为例,在使用该容器迭代一组数据时,必须事先将所有数据存储到容器中,才能开始迭代;而生成器却不同,它可以实现在迭代的同时生成元素。

    2.在用法上生成器只需要简单函数写法,配合yield就能实现。而迭代器真正开发中很难使用到。我们可以把生成器看做,python给我们提供的特殊接口实现的迭代器。

    (2)如何定义一个生成器

    不仅如此,生成器的创建方式也比迭代器简单很多,大体分为以下 2 步:

    1. 定义一个以 yield 关键字标识返回值的函数;
    2. 调用刚刚创建的函数,即可创建一个生成器;

    下面的代码分别使用生成器实现range和zip的功能。

    def generators(start=0, value=0, step=0):
        if start > value:
            raise Exception("开始值不能大于结束值!")
        while start < value:
            yield start
            start = start+step
    
    for i in generators(-5,5,2):
        print(i)
    
    list1 = ["a","b","c"]
    list2 = [1,2,3,4]
    
    def my_zip(*lists):
        min_len = min([len(l) for l in lists])
        index=0
        while min_len:
            yield tuple([x[index] for x in lists])
            index+=1
            min_len-=1
    
    dict1 = {}
    for x,y in my_zip(list1,list2):
        dict1[x] = y
    
    print(dict1) # {'a': 1, 'b': 2, 'c': 3}
    

    相关文章

      网友评论

          本文标题:(5) python 迭代器和生成器

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