Day11:迭代器与生成器

一、迭代器(iterator)

可迭代对象(iterable): 字符串,列表,元组,字典,集合等

  - 可迭代协议:含有“__iter__”方法的数据类型就是可迭代的

        - __iter__这个方法

        - 所学过的基本数据类型能被for循环的都是可迭代的(非迭代器)

迭代器(iterator):实现了能从其中一个一个的取出值来的东西

  - 迭代器协议:含有"__iter__" 和"__next__"方法

迭代器和可迭代对象之间的关系:

  - 迭代器包含可迭代对象

  - 迭代器 = 可迭代对象.__iter__

迭代器的本质:

  - 能够对python中的基本数据类型进行统一的遍历,

    不需要关心每一个值分别是什么

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

二、生成器(generator)

生成器就是迭代器,是自己写出来的一种类似函数的东西

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

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

从生成器中取值

  1.有几个yield就可以取几次

  2.for循环可对其正常取值

  3.其他数据类型可对其进行强制转换   例:list(g)

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

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

生成器的优点:

  - 延迟计算,一次返回一个结果。也就是说,它不会一次生成所有的结果,很适合处理大量的数据。

  - 提高代码可读性

生成器中需要注意的地方:

  - send和next工作的起止位置是完全相同的

  - send可以把一个值作为信号量传递到函数中去

  - 在生成器执行伊始,只能先用next

  - 只要有send传递参数的时候,必须在生成器中还有一个未被返回的yield

生成器相关面试题:

  - 面试题1

def demo():
    for i in range(4):
        yield i

g=demo()

g1=(i for i in g)
g2=(i for i in g1)

print(list(g1))
print(list(g2))

  - 面试题2

def add(n,i):
    return n+i

def test():
    for i in range(4):
        yield i

g=test()
for n in [1,10]:
    g=(add(n,i) for i in g)

print(list(g))

 

列表推导式和生成器表达式:

  - 列表推导式

new_l = []
for i in [1,3,5]:
    new_l.append(i*i)
print(new_l)

print([i*i for i in [1,3,5]])  

  - 生成器表达式

#从生成器表达式取值的三种方法
# 第一种
g = ((i*i for i in [1,3,5]))
print(list(g))

# 第二种
g = ((i*i for i in [1,3,5]))
for i in g:
    print(i)

# 第三种
g = ((i*i for i in [1,3,5]))
print(g.__next__())
print(g.__next__())
print(g.__next__())

 

posted @ 2017-09-04 15:37  世界辣么大  阅读(52)  评论(0)    收藏  举报