生成器、迭代器、可迭代对象

生成器、迭代器、可迭代对象

生成器

函数体中包含yield关键字的就是生成器
把生成 器传给 next(...) 函数时,生成器函数会向前,执行函数定义体中的 下一个 yield 语句,返回产出的值,并在函数定义体的当前位置暂停。等到再次遇到next才会继续执行。

简单生成器示例
def demo_gen():
    yield 1
    yield 2
    yield 3
gen = demo_gen()
print(next(gen))
print(next(gen))
print(next(gen))
print(next(gen))  # 当生成器的值取完了,在使用next方法,会抛出StopIteration错误
生成器表达式

生成器表达式是语法糖:完全可以替换成生成器函数,不过有时使用生成器表达式更便利。

代码在ipython(安装:pip install ipython)运行的

In [1]: (i for i in range(10))
Out[1]: <generator object <genexpr> at 0x107798200>
类示例代码:
class Sentence:
    """
    简单的生成器,使用yield关键字
    """

    def __init__(self, text):
        self.text = text
        self.words = RE_WORD.findall(self.text)

    def __iter__(self):
        for word in self.words:
            yield word

迭代器

使用while循环模拟迭代器
s = 'ABC'
it = iter(s)
while True:
  try:
    print(next(it))
  except StopIteration:
    del it
    break
实现迭代器的必备方法
  1. __next__

    返回下一个可用的元素,如果没有元素了,抛出StopIteration异常。

  2. __iter__

    返回self,以便在应该使用可迭代对象的地方使用迭代器,例如for循环中。

实现代码:
class IterableDemo:

    def __init__(self, text):
        self.text = text
        self.index = 0

    def __iter__(self):
        return iter(self)

    def __next__(self):
      """next方法的获取逻辑"""
        try:
            word = self.text[self.index]
        except IndexError:
            raise StopIteration
        self.index += 1
        return word

if __name__ == '__main__':
    it = IterableDemo('Hello,world')
    print(next(it))
    print(next(it))
    print(next(it))

可迭代对象

可迭代对象是指可以通过__iter____getitem__方法访问。

其中__getitem__方法没有办法通过issubclass(Sentence, Iterable)判断。

解释器需要迭代对象x时,会自动调用iter(x)

from collections.abc import Iterable

class Sentence:
  def __iter__(self):
    return iter(self)
  
print(issubclass(Sentence, Iterable)) # == True

class Sentence:
  def __getitem__(self, index):
    return self.words[index]
  
print(issubclass(Sentence, Iterable)) # == False

实现__getitem__方法

如果只实现了__getitem__方法,Python会创建一个迭代器,尝试按顺序(从索引0开始)获取元素。

如果尝试失败会返回C object is not iterable(C对象不可迭代),其中C对象就是所属的类。

def __getitem__(self, index):
  return self.words[index]
实现__iter__方法
def __iter__(self):
  return iter(self.words)
示例代码:
class Sentence:

    def __init__(self, text):
        self.text = text
        self.words = RE_WORD.findall(self.text)

    def __iter__(self):
        return iter(self.words)

    # def __getitem__(self, index):
    #     return self.words[index]

    def __len__(self):
        return len(self.words)

    def __str__(self):
        return 'Sentence(%s)' % reprlib.repr(self.words)


s = Sentence('Hello world how are you')
for word in s:
    print(word)
  • 20
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爬虫探索者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值