python里面的迭代器和生成器,讲得比较清楚

参考这篇文章:

https://blog.csdn.net/bqw18744018044/article/details/109149584?

 

一、迭代器、for循环、iter()方法
包含__iter__方法和__next__方法的对象就是迭代器对象,其中__iter__方法必须返回一个迭代器(自定义迭代器就直接返回self),__next__方法不依赖索引值的返回下一个元素。
for循环的本质是迭代器循环。例如for a in l,其默认会调用iter(l)来参数迭代器,然后循环调用next()函数。其原理类似于

l = [1,2,3]
it = iter(l)
next(it)
next(it)

 

  1. iter()方法首先会检查对象是否实现了__iter__方法,如果实现该方法则调用该方法来获得迭代器;如果没有实现该方法但实现了__getitem__方法,iter()方法会通过__getitem__来生成一个迭代器。例如:
复制代码
class MyIterator:
    def __init__(self):
        self.list = [1,2,3]
    
    def __getitem__(self, index):
        print("调用__getitem__")
        return self.list[index]
    
    def __len__(self):
        return len(self.list)

for i in iter(MyIterator()):
    print(i)
复制代码

输出

调用__getitem__
1
调用__getitem__
2
调用__getitem__
3
调用__getitem__

二、可迭代对象

只要实现了__iter__方法的对象都可称为可迭代对象。所以迭代器一定是可迭代对象,可迭代对象不一定是迭代器。下面的例子展示了迭代器和可迭代对象之间的关系。

复制代码
import re

RE_WORD = re.compile('\w+')
# 迭代器
class SentenceIterator:
    def __init__(self, words):
        self.words = words
        self.index = 0
    
    def __next__(self):
        try:
            word = self.words[self.index]
        except IndexError:
            raise StopIteration()
        self.index += 1
        return word
    
    def __iter__(self):
        return self
    
# 可迭代对象
class Sentence:
    def __init__(self, text):
        self.text = text
        self.words = RE_WORD.findall(text)
    
    def __iter__(self):
        return SentenceIterator(self.words)

for i in Sentence("a b c"):
    print(i)
复制代码

输出:

a
b
c

三、生成器与生成器表达式

1.生成器与迭代器

在python中使用yield的函数称为生成器。生成器本质上就是迭代器,是一种自定义的迭代器。因此,直接使用生成器来代替先前的迭代器SentenceIterator。

复制代码
import re

RE_WORD = re.compile('\w+')

class Sentence:
    def __init__(self, text):
        self.text = text
        self.words = RE_WORD.findall(text)
    
    def __iter__(self):
        for word in self.words:
            yield word
        return

for i in Sentence("a b c"):
    print(i)
复制代码

2.生成器表达式

生成器表达式形式上类似于列表推导,其能够通过简单的语法来实现生成器。下面的例子展示了不同的生成器创建方法

复制代码
# 通过yield来创建生成器
def f():
    for i in [1,2,3]:
        yield i
gen1 = f()
# 通过生成器表示式来创建生成器
gen2 = (i for i in [1,2,3])
print(type(gen1))
print(type(gen2))
复制代码

输出

<class 'generator'>
<class 'generator'>

四、标准库中的生成器函数

部分内置,另一部分位于itertools和functools。

 

 


 

posted @   blcblc  阅读(61)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
历史上的今天:
2020-04-04 各种层正则的方法,如BN,LN,IN,GN
2018-04-04 【Sofa】最近做的一些比赛的总结
2018-04-04 roc auc等各种指标的优缺点 F-score的含义 F1 F2-score的区别
2017-04-04 机器学习的一篇好文
2017-04-04 各个RFC
2017-04-04 端口相关的内容 REUSEADDR TIME_WAIT ipv4 tcp参数 MSL 报长-重要
2017-04-04 pps & Linux网络性能瓶颈
点击右上角即可分享
微信分享提示