迭代器 与 生成器

#############迭代器与生成器################

-可迭代对象与迭代器

  - 可迭代对象:像str,list,tuple,set,dict这样的数据类型,range

    - 如何检测是否为可迭代对象:看功能中是否包含‘双下iter’  __iter__,如果含有就是可迭代对象

    - 可迭代协议:数据类型和python解释器定下来的协议,只要包含了“双下iter”方法的数据类型就是可迭代的 —— 可迭代协议  

#方法一
print(dir('aaa'))           #其中包含   __iter__ 方法的就是可迭代对象     
#方法二
from collections import Iterable  #检测一个对象是否可迭代
print(isinstance('aaa',Iterable))      #True
print(isinstance(123,Iterable))       #False

  - 迭代器:可迭代对象.__iter__()   就是迭代器,作用就是一个一个的从其中向外拿值

    - 如何检测是否是迭代器:看功能中是否包含 __iter__和__next__这两个功能,如果含有就是迭代器

    - 迭代器协议:迭代器中有 __next__ 和 __iter__方法 —— 迭代器协议

lst_iterator = [1,2,3].__iter__()
from collections import Iterator
print(isinstance(lst_iterator,Iterator))          #True
print(isinstance([1,2,3],Iterator))                #False

    - 迭代器的方法:  __next__ ,   当迭代器中没有值往外拿是,继续__next__方法就会报错

#把迭代器赋值给一个变量,再操作变量进行.__next__()功能
lst_iterator = [1,2,3].__iter__() print(lst_iterator.__next__()) #1 print(lst_iterator.__next__()) #2 print(lst_iterator.__next__()) #3 #直接操作迭代器.__next__()功能 lst_iterator = [1,2,3].__iter__() print([1,2,3].__iter__().__next__()) #1 print([1,2,3].__iter__().__next__()) #1 print([1,2,3].__iter__().__next__()) #1

可以把[1,2,3].__iter__()看成一个函数,如果直接使用不赋值给变量,则每次都要重新调用函数

    - 迭代器:有天生是迭代器,比如文件句柄   ;   有后天改造成的,可迭代对象.__iter__()

- for循环 可以循环可迭代对象,也可以循环迭代器
  - 循环可迭代对象       每一个for循环都会从新开始

t=[1,2,3]
for i in t:
    print(i)   123
for i in t:
    print(i)   123

  - 循环迭代器        若第一个for循环完,下一个for循环将不会循环到值

t=[1,2,3].__iter__()
for i in t:
    print(i)    123
for i in t:
    print(i)      

  - for 循环的意义:

    - 1.能够对python中的基本数据类型进行统一的遍历,不需要关心每一个值分别是什么

    - 2.它可以节省内存 —— 惰性运算

- 生成器 : 生成器就是迭代器   只是生成器是自己写成的迭代器

  - 生成器函数:常规函数定义,使用yield语句而不是return语句返回结果。yield语句一次返回一个结果,在每个结果中间,挂起函数的状态,以便下次重它离开的地方继续执行

  -形式:一个包含yield关键字的函数就是一个生成器函数。yield可以为我们从函数中返回值,但是yield又不同于return,return的执行意味着程序的结束,调用生成器函数不会得到返回的具体的值,而是得到一个可迭代的对象。每一次获取这个可迭代对象的值,就能推动函数的执行,获取新的返回值。直到函数执行结束。

def generator_func():  #生成器函数
    print(123)
      yield 'aaa'  
      print(456)
      yield 'bbb'

g = generator_func()
ret = g.__next__()        # 123
print(ret)                # 'aaa'
ret = g.__next__()        # 456
print(ret)                # 'bbb'

  - 生成器与list(),tuple()

def generator_func():  
      yield 'aaa'   
      yield 'bbb'

g = generator_func()   
print(list(g))      #['aaa', 'bbb']

  - 生成器与for循环

def generator_func():  #生成器函数
    yield 'aaa'   
    yield 'bbb'
g = generator_func()
for i in g:
    print('i : ',i)     #i:aaa
                         #i:bbb
def get_clothing():
    for cloth in range(1,200):
        yield '第%s件衣服'%cloth

generate = get_clothing()
print(generate.__next__())   #   1
print(generate.__next__())   #   2
print(generate.__next__())   #   3
for i in generate:
    print(i)                             #   4-199

##########

def get_clothing():
    for cloth in range(1,200):
        yield '第%s件衣服'%cloth
generate = get_clothing()
for i in range(9):
    print(generate.__next__())               #    1-9
for i in get_clothing():                
    print(i)                                            #   1-101
    if i == '第101件衣服':
        break

  - 生成器的注意事项:

    - 带yield关键字的函数就是生成器函数

    - 生成器函数在执行的时候只返回一个生成器,不执行生成器函数中的内容

    - 从生成器中取值  

      - __next__ 有几个yield就可以取几次

      - for循环取值 正常取

      - 其他数据类型进行强制转换 list(g) 返回一个列表,里面装着生成器中的所有内容

      -注意:调用生成器函数的时候,要先获取生成器,再进行next取值

         生成器中的内容只能取一次,且按顺序取值没有回头路,取完为止。

   - yield from

def func():
    for i in [1,2,3]:
        yield i
    for j in 'ABC':
        yield j
g=func()
for i in g:
    print(i)    1,2,3,A,B,C

 

def func2():
    yield from [1,2,3]
    yield from 'q'
g = func2()
for i in func2():
    print(i)          1,2,3,q

 

posted @ 2017-09-04 17:16  JAYWX  阅读(91)  评论(0编辑  收藏  举报