骄傲的赛亚人

迭代器和生成器

Generator:生成器

Iterator:迭代器

Iterable:可迭代对象

 

 

可迭代对象

能够进行迭代逐一返回其成员项的对象称为可迭代对象。可迭代对象例子包括

  • 所有序列类型:如list、str、和tuple
  • 非序列类型:dict、set、文件对象
  • 实现了__iter__()方法的任意对象(可迭代协议)
  • 实现了序列语义的__getitem__()方法的任意对象

迭代协议和迭代器协议

迭代协议:

对象定义了一个__iter__方法的,那么这个对象就实现了迭代协议,__iter__方法的返回值必须是一个迭代器

迭代器协议:

迭代器协议由一个__iter__方法和__next__方法共同构成。实现了这两个方法的对象就实现了迭代器协议

  • 对象实现了迭代协议的对象
  • 对象实现了__next__方法,__next__方法在迭代完成数据后,会抛出StopIteration的错误信息

迭代器(Iterator)

定义表达式:tup=iter([23,32,44,54])

当迭代器中的数据,全部迭代完毕之后,再次进行迭代操作会报错,一次next只会返回一条数据

 

 

  • 实现了迭代器协议的对象,就是一个迭代器
  • 所有的可迭代对象,都可以通过内置函数iter()转换为迭代器
  • 迭代器对象能够使用内置函数next()进行迭代操作
  • 所有迭代器都是可迭代对象,因为迭代器协议包含了迭代协议

 

 生成器(Generator):

  • 当函数中有yield时,这个函数就是生成器函数,在调用函数的时候会返回一个生成器对象,调用不函数不会执行函数内部代码
  • 只有生成器进行迭代操作的时候,才会执行生成器函数的代码
  • 使用next()方法,就可以启动生成器函数执行,调用一次next()就执行一次

优点:节约内存

生成器表达式:

1、tup = (i for i in range(10)),tup返回的是一个生成器对象

2、用函数定义生成器

def func():

  print("---------start---------------")

  for i in range(100):

    yield i

    print('---------{}---------'.format(i))

 

res = func()
第一次迭代的时候执行到yield就会暂停,然后返回i的数据,下次执行生成器迭代  的时候,当遇到yield时会再次暂停

res1 = next(res)

res2 = next(res)

输出:

0

1

生成器函数调用时不会执行,直接返回一个生成器对象

生成器进行迭代操作的时候,才会执行生成器函数中的代码

使用next进行迭代,就可以启动生成器函数执行

 

生成器和迭代器的区别:

1、生成器和迭代器的迭代数据都使用内置函数next();

2、生成器有close()方法,来关闭生成器,关闭生成器后,不能在进行数据迭代

3、生成器可以用send()方法 和生成器内部数据进行交互,send方法必须在使用了next方法后,才能使用,或者在第一次使用send()的时候跟send()方法传一个None

4、生成器,可以使用throw()方法,往生成器内部主动抛出异常

 

生成器next()方法和send()方法的运用

两者区别:

实际上next()和send()在一定意义上作用是相似的,区别是send()可以传递yield表达式的值进去,而next()不能传递特定的值,只能传递None进去。因此,我们可以看做next(g) 和 g.send(None) 作用是一样的。

 

 

 

g=fun()     #创建生成器对象,不会立即执行

next(g)     #第一次执行next()方法时启动生成器,代码运行到第7行,然后跳出生成器

print(g.send("牛呀"))      #执行send()方法后再次进入生成器函数,运行yield后面的代码,然后重新运行到yield语句

备注:需要先执行next()方法后,才能执行send方法,否则会报错

输出:

a的值:牛呀

1

 

 

posted on 2022-02-22 11:49  骄傲的赛亚人  阅读(47)  评论(0编辑  收藏  举报

导航