2021-02-19 python迭代器

Python迭代器

  1. 迭代器是一个可以记住遍历的位置的对象
  2. 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退
  3. 迭代器有两个基本的方法:iter() 和 next()
  4. 字符串列表元组对象都可用于创建迭代器
list = [1,2,3,4]
it = lter()
print (next(it))  输出1
print (next(it))  输出2

迭代器对象可用for语言遍历:

list=[1,2,3,4]
it = iter(list)    # 创建迭代器对象
for x in it:
    print (x, end=" ")
 输出:1 2 3 4 

迭代器对象可以使用常规for语句进行遍历,不需要担心越界问题,因为迭代器内部存在着迭代终止标记StopIteration;

也可以使用next()函数:

import sys         # 引入 sys 模块
 
list=[1,2,3,4]
it = iter(list)    # 创建迭代器对象
 
while True:
    try:
        print (next(it))
    except StopIteration:
        sys.exit()
 输出: 	1
 	   	2
 	   	3
 	   	4

创建迭代器

  • 把一个类作为一个迭代器使用需要在类中实现两个方法 iter() 与 next() ;
  • iter() 方法返回一个特殊的迭代器对象, 这个迭代器对象实现了 next() 方法并通过 StopIteration 异常标识迭代的完成;
  • next() 方法会返回下一个迭代器对象;
class MyNumbers:
  def __iter__(self):
    self.a = 1
    return self
 
  def __next__(self):
    x = self.a
    self.a += 1
    return x
 
myclass = MyNumbers() 
myiter = iter(myclass)
 
print(next(myiter))
print(next(myiter))
print(next(myiter))
输出:
	1
	2
	3

StopIteration:

StopIteration 异常用于标识迭代的完成,防止出现无限循环的情况,在 next() 方法中我们可以设置在完成指定循环次数后触发 StopIteration 异常来结束迭代。

class MyNumbers:
  def __iter__(self):
    self.a = 1
    return self
 
  def __next__(self):
    if self.a <= 5:
      x = self.a
      self.a += 1
      return x
    else:
      raise StopIteration
 
myclass = MyNumbers()
myiter = iter(myclass)
 
for x in myiter:
  print(x)
输出:
	1
	2
	3
	4
	5

生成器

  1. 在 Python 中,使用了 yield 的函数被称为生成器(generator)
  2. 跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作;
  3. 在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行;
  4. 调用一个生成器函数,返回的是一个迭代器对象
def fab(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a + b
        n = n + 1
for i in fab(5):
    print(i)
  • yield 的作用就是把一个函数变成一个 generator,带有 yield 的函数不再是一个普通函数,Python 解释器会将其视为一个 generator,调用 fab(5) 不会执行 fab 函数,而是返回一个 iterable 对象!在 for 循环执行时,每次循环都会执行 fab 函数内部的代码,执行到 yield b 时,fab 函数就返回一个迭代值 b ,下次迭代时,代码从 yield b 的下一条语句继续执行,而函数的本地变量看起来和上次中断执行前是完全一样的,于是函数继续执行,直到再次遇到 yield;
  • 当函数执行结束时,generator 自动抛出 StopIteration 异常,表示迭代完成。在 for 循环里,无需处理 StopIteration 异常,循环会正常结束;

对比:

class Fab(object):

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

   def __iter__(self):
       return self

   def next(self):
       if self.n < self.max:
           r = self.b
           self.a, self.b = self.b, self.a + self.b
           self.n = self.n + 1
           return r
       raise StopIteration()
  • yield 的好处是显而易见的,把一个函数改写为一个 generator 就获得了迭代能力,比起用类的实例保存状态来计算下一个 next() 的值,不仅代码简洁,而且执行流程异常清晰。

参考链接:Python迭代器与生成器介绍及在Pytorch源码中应用

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值