python iterator & generator

迭代器iterator

  1. python中实现了__iter__方法的对象是可迭代的,实现了next()方法的对象是迭代器(要实现next()方法需要在类中实现__iter____next__方法);

  2. 一个类想被用于for...in...循环,类似for i in list:,就必须实现一个__iter__()方法,该方法返回一个迭代对象。然后,pythonfor循环就会不断调用该迭代对象的next()方法拿到循环的下一个值,直到遇到StopIteration错误时退出循环。

  3. 分类:
    在这里插入图片描述

  4. In fact this is how the for loop works, if we write

for x in iterator:
	<code block>

then the interpretor

  • calls iterator.__next__() and binds x to the result
  • executr the code bliok
  • repeats until a StopIteration error occurs

So, that means x = iterator.__next__().(迭代器本质上是每次调用__next__()方法都返回下一个元素或抛出StopIteration异常的容器对象)

  1. Formally, an object is iterable if it can be converted to an iterator using the built-in function iter().
  2. for loops work on either iterators or iterables. In the second case, the iterable is converted into an iterator before the loop starts.
  3. One thing to remember about iterators is that they are depleted by use.
"""采用迭代器生成斐波那契数列"""

class Fib(object):

    def __init__(self):
        
        self.a = 0
        self.b = 1


    def __iter__(self):

        return self


    def __next__(self):

        x, y = self.a, self.b
        self.a = self.a + self.b
        self.b = self.a + self.b
        return x, y


# 测试函数
def demo():
    fib = Fib()
    j = 1
    for i in fib:
        if j > 50:
            raise StopIteration
        
        print(i)
        j += 1


# 执行测试函数
if __name__ == '__main__':

    demo()
"""创建一个计数器类:迭代器"""

class Count(object):

    def __init__(self, max):
        self.max = max
        self.count = 0

    def __iter__(self):
        print('__iter__() has been called')
        return self

    def __next__(self):
        x = self.count
        if x < self.max:
            print('__next__() has been called')
            self.count += 1
            return x
        else: 
            print('StopIteration has been called')
            raise StopIteration


# 定义测试函数
def main():
    counter = Count(100)
    print('\n=== counter的内容:===')
    print(counter)
    print('\n=== counter的类型:===')
    print(type(counter))

    for i in counter:
        print(i)


# 执行测试函数
if __name__ == '__main__':

    main()

生成器generator

1. 概念

以 list 容器为例,在使用该容器迭代一组数据时,必须事先将所有数据存储到容器中,才能开始迭代;而生成器却不同,它可以实现在迭代的同时生成元素。也就是说,对于可以用某种算法推算得到的多个数据,生成器并不会一次性生成它们,而是什么时候需要,才什么时候生成。

2. 创建

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

3.示例

  • 一种创建generator的快捷方法:
L = [x * x for x in range(10)]   #使用[]创建的是列表对象,存有0-9的平方值
g = (x * x for x in range(10))   #使用()创建的是一个生成器对象
  • 采用yield关键字创建generator:
def intNum():
    print("开始执行")
    for i in range(5):
        yield i
        print("继续执行")

# 生成对象
num = intNum()     #num是一个生成器实例
print(num.__next__() )    #对num对象使用方法__next__(),函数运行至“yield i”暂停,输出"开始执行,0"
num.__next__()     #从暂停的地方继续执行,输出"继续执行,1"

# 或者使用for...in...直至raise StopIteration error终止循环
for i in num:
	print(i)

  • 自动触发生成器迭代示例:
import random

def f(n):
    i = 1
    while i <= n:
        yield random.uniform(0,1) < 0.5
        i += 1

ff = f(100)
print(sum(ff))  #没有对ff使用for或者next(),sum()函数似乎自动触发了生成器对象ff迭代
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

E. Zhao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值