python中迭代器和生成器

本文详细介绍了Python中的迭代器协议,包括__iter__和__next__方法,阐述了迭代器作为访问集合元素的方式,以及它与下标访问的区别。同时,讨论了生成器的概念,指出含有yield关键字的函数即为生成器函数,并通过实例展示了生成器在处理大量数据时节省内存的优势,如生成斐波那契数列和读取大文件等场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1)python的迭代器协议

问题:
1)迭代协议
__iter__
__next__
2)迭代器是什么?
迭代器是访问集合内元素的一种方式,一般用来遍历数据。迭代器和以下标访问的方式不一样,迭代器是不能返回的,迭代器提供了一种惰性方式访问数据。迭代器是实现了迭代协议 __iter__方法。


迭代器与可迭代对象的区别

我们查看下Iterator与Iterable类中分别实现了哪些协议。
只要实现了__iter__方法就是可迭代类型,迭代器必须也实现__next__方法。

class Iterable(metaclass=ABCMeta):

    __slots__ = ()

    @abstractmethod
    def __iter__(self):
        while False:
            yield None

    @classmethod
    def __subclasshook__(cls, C):
        if cls is Iterable:
            return _check_methods(C, "__iter__")
        return NotImplemented

    __class_getitem__ = classmethod(GenericAlias)


class Iterator(Iterable):

    __slots__ = ()

    @abstractmethod
    def __next__(self):
        'Return the next item from the iterator. When exhausted, raise StopIteration'
        raise StopIteration

    def __iter__(self):
        return self

    @classmethod
    def __subclasshook__(cls, C):
        if cls is Iterator:
            return _check_methods(C, '__iter__', '__next__')
        return NotImplemented

from collections.abc import Iterator,Iterable

lis = [1,2]
print(isinstance(lis,Iterable))
print(isinstance(lis,Iterator))
--------------------------------------------------
True
False

因为list只实现了 __iter__协议(Iterable),而没有实现__next__协议(Iterator)

from collections.abc import Iterator,Iterable

lis = [1,2]
iter_lis = iter(lis)
print(isinstance(lis,Iterable))
print(isinstance(iter_lis,Iterator))
-----------------------------------------
True
True

from collections.abc import Iterator,Iterable
class Myiterator(Iterator):
    def __init__(self,employ_list):
        self.employs_iter = employ_list
        self.index = 0

    #继承了Iterator就不用再实现
    # def __iter__(self):
    #     pass

    def __next__(self):
        try:
            words = self.employs_iter[self.index]
        except IndexError:
            raise StopIteration
        self.index += 1
        return words

if __name__ == '__main__':
    Myiterator = Myiterator(['a','b','c'])
    while True:
        try:
            print(next(Myiterator))
        except Exception:
            pass
------------------------------------------------
a
b
c
2)python生成器

1、 什么是生成器函数
只要又yield关键字就是生成器函数。

def gen_fun():
    yield 1

def fun():
    return 1
    
#生成器对象
gen = gen_fun()
fun = fun()
print(type(gen))
print(type(fun))
-------------------------------------
<class 'generator'>
<class 'int'>
def gen_fun():
    yield 1
    yield 2

gen = gen_fun()

for item in gen:
    print(item)
--------------------------------------------
1
2

通过一个例子来看下yield关键字
生成一组斐波那契数组
eg: [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

def fib(index):
    re_list = []
    n,a,b = 0,0,1
    while n < index:
        re_list.append(b)
        a,b = b,a+b
        n += 1
    return re_list
print(fib(99999))
-----------------------------------
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 14.....


import time
def fib(index):
    n,a,b = 0,0,1
    while n < index:
        yield b
        a,b = b,a+b
        n += 1
time1 = time.time()
for item in fib(99999):
    print(item)
time2 = time.time()
-------------------------------------
采用yield关键字不消耗过多内存

生成器读取大文件
一个500G的文件只有一行,以“{|}”分隔每行

在这里插入图片描述


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值