可迭代对象

  • 可迭代对象,可以通过循环遍历其中的元素,但是可迭代对象不一定是迭代器,比如说列表就是可迭代对象,但不是迭代器。 ```python from collections.abc import Iterator

li = [1,3,5,7,9]

print(isinstance(li, Iterator))

for i in li: print(i)

  1. ![image.png](https://cdn.nlark.com/yuque/0/2020/png/1325594/1594384309741-29b13dd4-41e9-4779-ac3b-157602bf3cba.png#align=left&display=inline&height=60&margin=%5Bobject%20Object%5D&name=image.png&originHeight=137&originWidth=1325&size=31121&status=done&style=none&width=576)
  2. <a name="r3FOL"></a>
  3. #### 迭代器
  4. - 可以通过iter()函数将可迭代对象转为迭代器
  5. - next() 方法可以将迭代器中的元素取出,并且不可逆
  6. - 在元素取完之后,再想取元素就会抛出异常StopIteration,因为已经没有元素可以取出来了,但是如果使用for循环遍历的话,实际上是使用的iter()方法,for可以自动捕获异常从而不会报错
  7. ```python
  8. from collections.abc import Iterator
  9. li = [1,3,5,7,9]
  10. li = iter(li)
  11. print(isinstance(li, Iterator))
  12. while True:
  13. print(next(li))

image.png

  • iter()就是对象的iter()魔法方法

    • 该方法返回一个可迭代对象
    • 只要对象中实现了iter()魔法方法,即可作为可迭代对象
  • next()就是对象的next()魔法方法

    • 可以将迭代器中的元素一个一个的取出
  • 对象只有同时拥有这两种魔法方法才能算迭代器,如果只有iter方法只能作为可迭代对象,并不是迭代器 ```python from collections.abc import Iterator

class MyIterator(Iterator): def init(self, num): self.num = num

  1. def __next__(self):
  2. # 如果num大于0 则返回num -= 1 否则主动抛出异常
  3. if self.num > 0:
  4. self.num -= 1
  5. return self.num
  6. raise StopIteration
  7. def __iter__(self):
  8. # 因为继承的就是Iterator 所以返回本身即是迭代器
  9. return self

my = MyIterator(2)

print(isinstance(my, Iterator))

print(next(my)) print(next(my)) print(next(my))

  1. ![image.png](https://cdn.nlark.com/yuque/0/2020/png/1325594/1594386330683-e6ed512c-6725-4caa-bb35-6584a12227d1.png#align=left&display=inline&height=101&margin=%5Bobject%20Object%5D&name=image.png&originHeight=201&originWidth=1243&size=80538&status=done&style=none&width=621.5)
  2. <a name="8kTnz"></a>
  3. #### 生成器
  4. - 当函数使用yield语句时,可将函数挂起,等待下一次的继续运行,功能类似于迭代器。
  5. - 如果一个可迭代对象占用空间特别大,其中元素可以使用某种算法推导出来,则可以使用生成器
  6. ```python
  7. from collections.abc import Generator
  8. g = (i for i in range(10))
  9. print(isinstance(g, Generator))
  10. for i in g:
  11. print(i)

image.png

  • 如果一个函数需要被多次调用,并且可以每次需要传递参数,可以使用yield回调参数然后挂起
    • 可以通过send发送参数,实现相互通信
    • 生成器函数效率更高,可以按需调用
    • 可以通过yield实现协程

image.png
image.png

友情链接:https://www.jianshu.com/p/1b0686bc166d