python迭代器和生成器

生成器是什么?

做循环的时候,我们常常会先获取一个列表,用for语句去循环这个列表当中的元素。但是有时候列表的获取会受到限制,例如创建一个包含100万个元素的列表,会占用很大的存储空间,再比如有时我们只需要访问列表当中的前几个元素,不需要将列表完全生成出来。在这种受到限制的情况下,我们可以用生成器来解决问题。

在Python中,这种一边循环一边计算的机制,称为生成器。通过一边循环一边计算可以节省内存空间。

生成器的创建方法

方法一: 用小括号+for的表达式,这是生成器创建最简单的方法

>>> L = [x * x for x in range(10)]
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> g = (x * x for x in range(10))
>>> g
<generator object <genexpr> at 0x1022ef630>

创建L和g的区别仅在于最外层的[]和(),L是一个list,而g是一个generator。

方法二: 生成器函数
如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个生成器。函数运行时每次执行到一个yield,就会暂停,生成一个值给函数的调用者。当下一次回到这个函数时,将从上次暂停处继续执行。当执行到函数末尾或者return语句时,抛出StopIteration的异常,return的值保存在StopIteration异常对象的value字段中。

用这种形式接受生成器函数的值,得到的是一个生成器对象,而不是生成器函数生成的值:

def Gen():
    for i in range(5):
        yield i


a = Gen()
print(a)

打印的结果
在这里插入图片描述

正确的方法如下:

for i in a:
    print(i)

生成器的使用

方法一:可以用next函数,每次调用返回下一个结果。如果到了最后一个元素,将抛出StopIteration的异常。

方法二:用for循环。需要注意的是用for循环无法获取return的结果。如果需要return的结果,要用while循环。

迭代器是什么?

可以用next读取下一个对象的类型统称为迭代器Iterator。因此生成器也是一种迭代器。

集合数据类型(例如list set等)不是Iterator,而是可迭代类型Iterable。可迭代类型Iterable指的是可以用iter函数转为迭代器的类型。iter函数的原型是类当中预定义的__iter__函数,因此可迭代类型也可以理解为是定义了__iter__函数的类型。这个函数在for循环当中会被隐式调用。例如

for x in [1, 2, 3, 4, 5]:
    pass

这里就隐式调用了__iter__方法。

我们可以给类自定义__iter__函数,将这个类的对象变成迭代器,从而在for当中调用。

__iter____next__函数的差别

__iter__函数在for循环的开始处调用,生成一个支持next函数的对象,在for循环中对这个对象执行next操作。

__next__定义了对象在直接被执行了next时的表现。

比如这个例子:

class IterTest:
    def __init__(self):
        self.IterList = [1, 2, 3, 4, 5]
        self.NextList = iter([6, 7, 8, 9, 10])

    def __next__(self):
        print("执行了__next__函数")
        return self.NextList.__next__()

    def __iter__(self):
        print("执行了__iter__函数")
        return iter(self.IterList)


if __name__ == '__main__':
    it = IterTest()
    print('next函数调用的------')
    while True:
        try:
            a = next(it)
            print(a)
        except StopIteration:
            break

    print('for循环调用的------')
    for i in it:
        print(i)

输出:
在这里插入图片描述

可以看出在for循环中调用了__iter__,输出了self.IterList这个序列的值,在next函数中调用了__next__,输出了self.NextList的值

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值