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

先上本文主题:

  1. 迭代器一定是可迭代对象,可迭代对象不一定是迭代器;
  2. 可迭代对象要满足什么条件才能使用 for 正确遍历;
  3. 生成器一定是迭代器.

如何判断是否是迭代器/可迭代对象

from collections.abc import Iterator,Iterable

t = []
# 是否为迭代器
isinstance(t,Iterator)
# 是否为可迭代对象
isinstance(t,Iterable)

可迭代对象

实现了__iter__魔法方法,就是可迭代对象.

class Test:
  def __iter__(self):
      pass

t = Test()

print(isinstance(t,Iterable)) # True
print(isinstance(t,Iterator)) # False

迭代器

实现了__iter____next__魔法方法,就是可迭代对象.

class Test:
  def __iter__(self):
      pass

  def __next__(self):
      pass

t = Test()

print(isinstance(t,Iterable)) # True
print(isinstance(t,Iterator)) # True

从上面两个条件可以推导出,迭代器一定是可迭代对象

一个对象要满足什么条件才能被使用 for 进行遍历

  1. 该对象需要是一个可迭代对象,即实现了__iter__方法;
  2. __iter__方法返回一个实现了__next__方法的对象;
class A:
  def __next__(self):
    return 'hello world'

a = A()

class B:
  def __iter__(self):
      return a

b = B()
# 每次循环都会调用a的__next__方法获取返回值.
for i in b:
  print(i)

输出如下:

hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
...

上面两个 class 组合在起义的写法如下:

class B:
  def __iter__(self):
      return self

  def __next__(self):
    return 'hello world'

b = B()
for i in b:
  print(i)

这里的关键点就是在__iter__方法中返回的self,因为 class 实现了__next__方法,所以返回self正好满足第二个条件.

生成器和迭代器的关系

生成器自动实现了迭代器的协议

为什么这样说呢?
返回生成器对象一共有两种方式:

  1. 生成器表达式;
  2. 调用含有 yield 的函数.

以第一种方式为例

In [1]: a = (i for i in range(10))

In [2]: a.__next__
Out[2]: <method-wrapper '__next__' of generator object at 0x10d3f2ed0>

In [3]: a.__iter__
Out[3]: <method-wrapper '__iter__' of generator object at 0x10d3f2ed0>

可以看到,虽然我们并未显示定义,但是生成器表达式确实实现了__iter____next__方法,通过yield关键字定义的生成器同样拥有这样的特性,所以说,生成器自动实现了迭代器的协议.生成器一定是迭代器.

原文地址:https://www.cnblogs.com/aloe-n/p/12242493.html

时间: 2024-10-10 11:13:03

迭代器/可迭代对象/生成器的相关文章

迭代器&amp;迭代对象&amp;生成器

迭代器 & 迭代对象 & 生成器 包含__next__ 和 __iter__两个方法的对象为迭代器 __next__方法返回单个元素 __iter__方法返回迭代器本身 可迭代对象包含__iter__方法,每次都实例化一个新的迭代器 因此,迭代器可以迭代,但是可迭代对象不一定是迭代器 生成器是一种特殊的迭代器 import re import reprlib RE_WORD = re.compile('\w+') class Sentence: def __init__(self, tex

王亟亟的Python学习之路(七)-date,continue,迭代对象,生成器

转载请注明出处:王亟亟的大牛之路 大多数的语言都提供了时间操作的相应类,诸如java的java.util.Date,java.util.Calendar等等, Python中是time 和 calendar . 首先需要导包import time; 然后就可以使用了,mTime= time.time()那结果呢? 1448004021.1337154 (而且这个数字还继续在变) WHY? 用ticks计时单位返回从12:00am, January 1, 1970(epoch) 开始的记录的当前操

迭代器&amp;可迭代对象

迭代器 能够被next调用, 并不断返回值的一个对象惰性排序, 一次只获取一个数据, (占用一个空间)迭代器可以遍历无限量的数据 特点: 1.惰性序列, 节省内存 2.遍历使用next, 方向不可逆 3.迭代器可以遍历无限量大的数据 1. 可迭代对象 1 # 判断是不是可迭代对象 2 # 使用dir(obj) 看是否实现__iter__ 3 setvar = {1, 2, 4, 5} 4 print('__iter__' in dir(setvar)) 5 6 7 """ 8

Python——迭代器&amp;可迭代对象

可迭代对象 什么是对象: Python中,一切皆对象.一个变量,一个列表,一个字符串,文件句柄,函数等等都可称为一个对象.一个对象就是一个实例,就是实实在在的东西. 什么是迭代 迭代就是一个重复的过程,但还不是单纯的重复,就像是父亲,自己,儿子,孙子的关系,都是复制,但结果是不一样的.还有使用的APP,微信,抖音等隔一段时间就会基于上一次做一些更新,那么这就是迭代. 结论: 可迭代对象从字面意思就是一个可以重复取值的实施在在的东西. 不可迭代的有: 在Python中,有很多可迭代对象,那么就说说

可迭代对象,迭代器(对象),生成器(对象)

迭代器 可迭代对象:可迭代对象实现了__iter__方法,该方法返回一个迭代器对象. 迭代器: 那么什么迭代器呢?它是一个带状态的对象,他能在你调用next()方法的时候返回容器中的下一个值,任何实现了__iter__和__next__()(python2中实现next())方法的对象都是迭代器,__iter__返回迭代器自身,__next__返回容器中的下一个值,如果容器中没有更多元素了,则抛出StopIteration异常. a = ['aaa', 'bbb', 'ccc'] my_iter

完全理解 Python 迭代对象、迭代器、生成器

2017/05/29 · 基础知识 · 9 评论 · 可迭代对象, 生成器, 迭代器 原文出处: liuzhijun 本文源自RQ作者的一篇博文,原文是Iterables vs. Iterators vs. Generators,俺写的这篇文章是按照自己的理解做的参考翻译,算不上是原文的中译版本,推荐阅读原文,谢谢网友指正. 在了解Python的数据结构时,容器(container).可迭代对象(iterable).迭代器(iterator).生成器(generator).列表/集合/字典推导式

python基础一 ------利用生成器生成一个可迭代对象

#利用生成器生成一个可迭代对象#需求:生成可迭代对象,输出指定范围内的素数,利用生成器产生一个可迭代对象#生成器:本身是可迭代的,只是 yield 好比return返回,yield返回后函数冻结状态,当再次调用时从冻结状态开始 1 class PrintNumbers(object): 2 """docstring for PrintNumbers""" 3 def __init__(self, start,end): 4 self.start

可迭代对象和迭代器

1.首先可以用于for循环的对象统称为可迭代对象(Interable),像list dict str都是可迭代对象.可以被next()函数调用并不断返回下一个值的对象成为迭代器(Interable).看一下函数的实现: class Iterable(metaclass=ABCMeta): __slots__ = () @abstractmethod def __iter__(self): ##使用__iter__是迭代对象变为迭代器 while False: yield None @classm

Python 函数名,可迭代对象及迭代器

函数名是什么?1,函数名就是函数的内存地址a = 2b = ac = bprint(c)2,函数名可以作为变量.def func1(): print(666)f1 = func1()f2 = f1print(f2)3,函数名可以作为函数的参数.def func1(): print(666)def func2(x): print(x) x()print(func1)函数名可以当做函数的返回值.def wapper(): def inner(): print('inner') return inne