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 @ 2022-04-04 22:16  blcblc  阅读(45)  评论(0编辑  收藏  举报