迭代器和生成器区别

总结:

  • 生成器:generator
    yield作用就算将一个函数变成一个生成器

    • 可以作用for循环,也可作用next()函数
  • 迭代器(Iteraor):是一个可以记住遍历对象位置的对象

    • 可以作用for循环,也可作用next()函数

    • __iter__ 返回一个特殊的迭代器对象,这个迭代器对象实现了 __next__

    • __next__

  • 判断是否可迭代(Iterable)
    可以使用 isinstance()判断是否为Iterable对象

    • 可以作用for循环
  • 序列可以迭代是因为实现了iter()方法,或者实现了getitem方法且其参数是从零开始的索引

而生成器不但可以作用于for循环 还可以被next()函数不断调用并返回下一个值。直到抛出StopIteration错误表示无法继续返回下一个值。

生成器都说Iteraor迭代器对象,但list、dict、str虽然是Iterable却不是Iterator。
把他们变成迭代器Iterator可以使用iter()函数

Iterable可以作用于for循环 但是没有next()函数
Iterator即可作用于for循环 也可作用next()函数

以下来自

序列可以迭代的原因:iter函数。解释器需要迭代对象x时候,会自动调用iter(x),内置的iter函数有以下作用:

  1. 检查对象是否实现了 iter 方法,如果实现了就调用它,获取一个迭代器。

  2. 如果没有实现 iter 方法,但是实现了 getitem 方法,而且其参数是从零开始的索引,Python 会创建一个迭代器,尝试按顺序(从索引 0 开始)获取元素。

  3. 如果前面两步都失败,Python 抛出 TypeError 异常,通常会提示“C objectis not iterable”(C 对象不可迭代),其中 C 是目标对象所属的类。

    可迭代的对象: 使用 iter 内置函数可以获取迭代器的对象。即要么对象实现了能返回迭代器的 iter 方法,
    要么对象实现了 getitem 方法,而且其参数是从零开始的索引。

class myiter:
    def __init__(self, text):
        self.text = text
        self.sub_text = text.split(' ')
     # 实现了 __getitem__方法 是可迭代对象
	def __getitem__(self, index):
        return self.sub_text[index]
    
 
text_1 = myiter('hello my new world')
for i in text_1:
    print(i)

输出:

hello
my
new
world

迭代器

标准的迭代器接口有两个方法:

  • __next__ 返回下一个可用的元素,没有则抛出StopIteration异常

  • __iter__ 返回self,以便在应该使用可迭代对象的地方使用迭代器,例如for

class MyIter:
    def __init__(self, text):
        self.text = text
        self.sub_text = text.split(' ')
        self.index = 0

    # 返回一个特殊的迭代器对象,这个迭代器对象实现了 __next__方法并且通过StopIteration异常标识迭代的完成
    def __iter__(self):
        return MyIter2(self.sub_text)


# 自己构建的一个迭代器。
class MyIter2:
    def __init__(self, sub_text):
        self.sub_text = sub_text
        self.index = 0

    def __next__(self):
        try:
            subtext = self.sub_text[self.index]
        except IndexError:
            raise StopIteration()
        # 迭代偏移量
        self.index += 1
        return subtext

    def __iter__(self):
        return self


text_1 = MyIter('hello my new world')
for i in text_1:
    print(i)

可见结果也是

hello
my
new
world

我们通过两种方法实现了一个自己的可迭代对象,再此过程中我们要明确可迭代的对象和迭代器之间的关系:

  • iter方法从我们自己创建的迭代器类中获取迭代器,
    而getitem方法是python内部自动创建迭代器

还可以使用yield实现、或者迭代器表达式

class MyIter:
    def __init__(self, text):
        self.text = text
        self.sub_text = text.split(' ')
        self.index = 0

    def __iter__(self):
        for item in self.sub_text: 
            yield item
        # 或者
        yield from self.sub_text
        # 或者
        return (item for item in self.sub_text)

总结

什么是可迭代对象? 可迭代对象要么实现了能返回迭代器的 iter 方法,要么实现了 getitem 方法而且其参数是从零开始的索引。

(2)什么是迭代器? 迭代器是这样的对象:实现了无参数的 next 方法,返回下一个元素,如果没有元素了,那么抛出 StopIteration 异常;并且实现iter 方法,返回迭代器本身。

(3)什么是生成器? 生成器是带有 yield 关键字的函数。调用生成器函数时,会返回一个生成器对象。

(4)什么是生成器表达式? 生成器表达式是创建生成器的简洁句法,这样无需先定义函数再调用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值