Python进阶--生成器和迭代器以及实现方法

生成器和迭代器

  • generator: ⽣成器是一种特殊的迭代器, 不需要⾃定义 __iter__ 和 __next__

⽣成器函数 (yield)

def foo(): 
   ...:     print(111) 
   ...:     yield 222 
   ...:     print(333) 
   ...:     yield 444 
   ...:     print(555) 
   ...:                                                                                                                             

In [2]: n=foo()                                                                                                                     

In [3]: next(n)                                                                                                                     
111
Out[3]: 222

In [4]: next(n)                                                                                                                     
333
Out[4]: 444

In [5]: next(n)                                                                                                                     
555
---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-5-0fa053c92e6d> in <module>
----> 1 next(n)

StopIteration: 

⽣成器表达式: (i*2 for i in range(5))  这里使用的是括号(),list是[ ].

In [9]: gen = (i*2 for i in range(5))                                           

In [10]: print(gen)                                                             
<generator object <genexpr> at 0x10e73a200>
  • iterator:任何实现了__iter__和__next__方法的对象都是迭代器

  1. __iter__ 得到一个迭代器。迭代器的 __iter__() 返回自身
  2. __next__ 返回迭代器下一个值
  3. 如果容器中没有更多元素, 则抛出 StopIteration 异常
  4. Python2中没有 __next__() , ⽽是 next()
class Range:
    def __init__(self, start, end=None, step=1):
        if end is None:
            self.end = start
            self.start = 0
        else:
            self.start = start
            self.end = end
        self.step = step

    def __iter__(self):

        return self

    def __next__(self):
        if self.start < self.end:
            current = self.start
            self.start += self.step
            return current
        else:
            raise StopIteration()


Iter = Range(1, 4)

结果:
In [10]: print(next(Iter))                                                                                                          
1

In [11]: print(next(Iter))                                                                                                          
2

In [12]: print(next(Iter))                                                                                                          
3

In [13]: print(next(Iter))                                                                                                          
---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-13-2439b2fba63d> in <module>
----> 1 print(next(Iter))

<ipython-input-9-f1a6fab34350> in __next__(self)
     19             return current
     20         else:
---> 21             raise StopIteration()
     22 
     23 

StopIteration: 

  • str / bytes / list / tuple / dict / set ⾃身不是迭代器,他们自身不具备 __next__() , 但是具有 __iter__() , __iter__() 方法用来把⾃身转换成一个迭代器

练习:

# 练习1: 定义⼀一个随机数迭代器器, 随机范围为[1, 50], 最⼤大迭代次数3

import random

class RandomIter:
    def __init__(self, start, end, times):
        self.start = start
        self.end = end
        self.count = times

    def __iter__(self):
        return self

    def __next__(self):
        self.count -= 1
        if self.count >= 0:
            return random.randint(self.start, self.end)
        else:
            raise StopIteration()

RandomIter = RandomIter(1,50,3)
print(next(RandomIter))
print(next(RandomIter))
print(next(RandomIter))
print(next(RandomIter))
# 练习2: ⾃定义一个⽣成器函数, 实现斐波那契数列


def fib(max_value):
    prev = 0
    curr = 1
    while curr < max_value:
        yield curr
        prev, curr = curr, curr + prev

for i in fib(20):
    print(i, end=' ')

结果:1 1 2 3 5 8 13

各种推导式
分三部分:⽣成值的表达式, 循环主体, 过滤条件表达式
列表: [i*3 for i in range(5) i f %2 == 0]
字典: {i: i + 3 for i in range(5)}
集合: {i for i in range(5)}
生成器: (i for i in range(5))

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值