栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Python 迭代器和生成器的使用方法

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Python 迭代器和生成器的使用方法

这两天准备用Pytorch复现一些论文,所以也顺便熟悉了一下Pytorch在Python部分的实现,发现Pytorch用到了很多Python迭代器方面的语法。

所以准备先介绍一下Python中迭代器和生成器的使用,之后再介绍Pytorch的一些内部实现。

目录

1.前言

2.预备知识

2.1 什么是迭代器对象?

2.2 什么是可迭代对象?

3. for循环遍历可迭代对象的逻辑

4. 分离可迭代对象和迭代器对象

5. 如何显式地从可迭代对象中得到迭代器对象(iter函数)?

6. 如何显式地对迭代器对象进行迭代(next函数)?

7. 生成器:利用函数创建可迭代的迭代器对象

8. 如何对迭代器进行多次遍历?

9. 参考资料


1.前言

迭代器的好处不用多说,就是节省内存。这里主要介绍Python中迭代器和生成器的使用方法。

2.预备知识

2.1 什么是迭代器对象?

迭代器对象就是拥有__next__方法的对象。

通常我们不会单独使用迭代器对象。

2.2 什么是可迭代对象?

可迭代对象就是拥有了__iter__方法的对象。

注意一个对象可以同时是迭代器对象和可迭代对象(即既实现了__iter__方法,又实现了__next__方法)下文中我将称这类对象为可迭代的迭代器对象。

3. for循环遍历可迭代对象的逻辑

这里我想先介绍一下迭代器最常见的一个使用场景:for循环。

然后再剖析里面的一些细节。

class MyNumbers:
  def __init__(self):
    self.a = 1
  def __iter__(self):
    return self
  def __next__(self):
    x = self.a
    self.a += 1
    return x

mn = MyNumbers():
for i in  mn:
    print(i)
"""
输出结果:
1
2
3
4
5
6
∞
"""

这里我实现了一个MyNumbers类,这个类实现了__iter__和__next__方法。其中__iter__方法返回的是自己。这也是一般的可迭代对象的方式,即既实现__iter__,又实现__next__。

for循环的内部逻辑其实也不复杂,首先for循环会调用可迭代对象的__iter__方法,得到一个迭代器对象,之后再循环调用这个迭代器对象的__next__方法。

按照这个逻辑,我们可以分别在两个类中实现__iter__和__next__方法。

4. 分离可迭代对象和迭代器对象

大多数样例代码会在同一个类中实现__iter__和__next__方法,这里我提供一个分开实现的示例。

即让MyNumbers类实现__next__方法;Iterable类实现__iter__方法。这样做也是可以的。

class MyNumbers:
  def __init__(self):
    self.a = 1
  def __next__(self):
    x = self.a
    self.a += 1
    return x

class Iterable:
  def __init__(self,Iterator):
    self.Iterator = Iterator
  def __iter__(self):
    return self.Iterator

Iterator = MyNumbers()
Iterable_object = Iterable(Iterator)

for i in Iterable_object:
    print(i)

5. 如何显式地从可迭代对象中得到迭代器对象(iter函数)?

一般来说我们都是在for循环中隐式地调用可迭代对象的__iter__方法来获得迭代器对象,但是也可以显式地获得迭代器。

iter函数或者直接调用__iter__方法都是可以的。

class MyNumbers:
  def __init__(self):
    self.a = 1
  def __iter__(self):
    return self
  def __next__(self):
    x = self.a
    self.a += 1
    return x
mn = MyNumbers()

print(type(iter(mn)))
print(type(mn.__iter__()))

6. 如何显式地对迭代器对象进行迭代(next函数)?

同样,for循环中对__next__方法的调用也是隐式的,我们可以用next函数,或者__next__方法直接对迭代器对象进行迭代。

class MyNumbers:
  def __init__(self):
    self.a = 1
  def __iter__(self):
    return self
  def __next__(self):
    x = self.a
    self.a += 1
    return x
mn = MyNumbers()

print(next(mn))
print(mn.__next__())
print(next(mn))
print(mn.__next__())
"""
输出:
1
2
3
4
"""

7. 生成器:利用函数创建可迭代的迭代器对象

上面我们已经了解了,通过在类中实现__iter__和__next__方法,可以创建可迭代对象,迭代器对象或者可迭代的迭代器对象。

下面介绍另一种通过函数来得到可迭代的迭代器对象的方法,

而这种通过函数同时实现了__iter__和__next__方法的对象也可以被称为生成器。

注意生成器和可迭代的迭代器对象是存在区别的。

这个例子中,我创建了一个MyNumbers类的生成器版。

可以看到通过调用具有yield关键字的函数,可以得到一个generator类的实例。

def fun_mynumbers(upper_bound):
    x=1
    while True:
        if(x > upper_bound):
            return
        yield x
        x+=1
print(type(fun_mynumbers))

mn_generator = fun_mynumbers(10)

print(type(mn_generator))
print(type(mn_generator.__iter__))
print(type(mn_generator.__next__))

"""
输出结果:




"""

接下来遍历这个生成器,可以发现在用for循环遍历了生成器一遍之后,再次对生成器调用__next__方法就会报StopIteration错。这就是生成器和一般可迭代的迭代器对象的不同。

for i in mn_generator:
    print(i)
mn_generator.__next__()
"""
输出结果:
1
2
3
4
5
6
7
8
9
10
StopIteration                             Traceback (most recent call last)
/tmp/ipykernel_38/2244425320.py in 
      4 for i in mn_generator:
      5     print(i)
----> 6 mn_generator.__next__()

StopIteration: 
"""

8. 如何对迭代器进行多次遍历?

所以之后我会展示一个可以多次遍历的可迭代的迭代器对象。

可以看到这里之所以可以多次遍历,就是因为在实现__next__方法的时候会先判断当前要输出的值是否超过上界,假如没超过,那么正常输出,假设超过了,那么将当前的值重置,并且结束这次遍历。

class MyNumbers:
  def __init__(self,upper_bound):
    self.upper_bound = upper_bound
    self.a = 1
  def __iter__(self):
    return self
  def __next__(self):
    if(self.a < self.upper_bound):
        x = self.a
        self.a += 1
        return x
    else:
        self.a = 1
        raise StopIteration
mn = MyNumbers(5)

for i in mn:
    print(i)

for i in mn:
    print(i)

"""
输出结果:
1
2
3
4
1
2
3
4
"""

9. 参考资料

​​​​​​Python3 迭代器与生成器 | 菜鸟教程

python的迭代器为什么一定要实现__iter__方法? - 知乎

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/354983.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号