迭代器和生成器

一、迭代器

之前我们一直在用可迭代对象进行迭代操作,那么到底什么是可迭代对象。str,list,tuple,dict,set这些都是可迭代对象,因为它们都遵循可迭代协议。查看对象是否可迭代可以使用dir(对象)再把其打印出来如果其中有__iter__就说明其属于可迭代对象。

for循环使用的就是迭代原则,一开始是用__iter__()来获取迭代器,后面每次获取元素都是通过__next__()完成,当程序遇到StopIteration结束循环。

什么叫做迭代器?迭代器英文意思是iterator。

l = [1,2,3,4]
l_iter = l.__iter__() # 将可迭代的转化成迭代器
item = l_iter.__next__()
print(item)
item = l_iter.__next__()
print(item)
item = l_iter.__next__()
print(item)
item = l_iter.__next__()
print(item)
item = l_iter.__next__()
print(item)

迭代器遵循迭代器协议:必须拥有__iter__方法和__next__方法。

for循环,能遍历一个可迭代对象,他的内部到底进行了什么?

  • 将可迭代对象转化成迭代器。(可迭代对象.__iter__())
  • 内部使用__next__方法,一个一个取值。
  • 加了异常处理功能,取值到底后自动停止。

用while循环模拟for循环:

l = [1,2,3,4]
l_iter = l.__iter__()
while True:
  try:
    item = l_iter.__next__()
    print(item)
  except StopIteration:
    break

二、生成器

生成器的实质就是迭代器

在python中有三种方式来获取生成器:

1.通过生成器函数

2.通过各种推导式来实现生成器

3.通过数据转换也可以获取生成器

def func():

  print("111")

  yield 222

ret = func()

print(ret)

此时就生成了一个生成器,由于函数中存在yield那么这个函数就是一个生成器函数。如何来执行这个函数呢,见下面:

那么我们看到,yield和return的效果是一样的有什么区别呢?yield是分段来执行一个函数,return是直接停止执行函数。

当程序运行完最后一个yield,那么后i按继续进行__next__()程序会报错。

def cloth():
for i in range(0,10000):
yield "衣服"+str(i)
cl = cloth()
print(cl.__next__())
print(cl.__next__())
print(cl.__next__())
区别:第一种是直接一次性全部拿出,会很占内存第二种使用生成器,一次就生成一个,用多少生成多少。生成器是一个一个地指向下一个
不会回去,__next__()到哪,指针就指到哪。下一次继续获取指针指向的值。
接下来我们来看send方法,send和__next__()一样都可以让生成器执行到下一个yield.

send和__next__()的区别:

1.send和next()都是让生成器走下一次

2.send可以给上一个yield的位置传递值,不能给最后哦的一个yield发送值。在第一次执行生成器代码的时候不能用send()  

注:send比__next__多了个向上一个yield传值的功能不过第一个yield跟最后一个都传不到


认真做一件事,并将之完全学会掌握为止!
原文地址:https://www.cnblogs.com/wr13640959765/p/9198400.html