函数之迭代器生成器

一.迭代器

1.什么是迭代器?

迭代取值的工具

2.为什么要用迭代器?

在不利用for循环取值的情况下,我们分别对 字符串,列表,字典,元组,集合进行取值。我们发现字典和集合无法取值,因为他们俩都是无序的,不能利用索引取值,所以这时候我们就用到了迭代器。

迭代器给我们提供了一种不依赖索引取值的方式

3.如何用迭代器?

首先引入一个可迭代对象概念

只有内置有__iter__方法的都叫做可迭代对象

__iter__  读作  双下+方法名

在基本数据类型中可迭代对象有:str  list     tuple  dict  set  文件对象

之后我们就可以再介绍迭代器对象

1.内置有__iter__方法

2.内置有__next__方法

ps:迭代器一定是可迭代对象,而可迭代对象不一定是迭代器对象

#生成一个迭代器对象
l = [1,2,3,4]
iter_l = l.__iter__()
#迭代器取值 调用__next__
print(iter_l.__next__())
print(iter_l.__next__())
print(iter_l.__next__())
print(iter_l.__next__())
print(iter_l.__next__())  #如果取完了,就会报错
f1 = open('xxx.txt','r',encoding = 'utf-8')
#调用f1 内置的__iter__方法
iter_f =f1.__iter__()
print(iter_f is f1)
#True

迭代器对象无论执行多少次__iter__方法得到的还是迭代器本身(********)

上面有个问题,如果取多了里面没有值了的话,就会报错

下面我们进行异常处理

while True:
    try:
        print(iter_d.__next__())
    except StopIteration:
        break

迭代器取值的特点:  只能往后依次取,不能后退

for循环的本质

for循环内部的本质

  1.将in后面的对象调用__iter__转换成迭代器对象

  2.调用__next__迭代取值

  3.内部有异常捕获StopIteration,当__next__报这个错,自动循环结束

下面总结一下迭代器:

可迭代对象:内置有__iter__方法的
迭代器对象:既内置有__iter__也内置有__next__方法

迭代取值:
    优点
      1.不依赖于索引取值
      2.内存中永远只占一份空间,不会导致内存溢出

    缺点
      1.不能够获取指定的元素
      2.取完之后会报StopIteration错

 

二.生成器

1.什么是生成器?

用户自定义的迭代器,本质就是迭代器

def func():
    print('first)
    yield 666
    print('second')
    yield 777
    pirnt('third')
    yield 888
    print('forth')
    yield
# yield后面跟的值就是调用迭代器__next__方法你能得到的值
# yield既可以返回一个值也可以返回多个值 并且多个值也是按照元组的形式返回
g = func()
print(g)
print(g.__next__)
print(g.__next__)
print(g.__next__)
print(g.__next__)
print(g.__next__)

例子: 

for i in range(1,10,2):
    print(i)

将上面的写成一个生成器

def my_range(start,end,step=1)
    while start<end:
        yield start
        start+=step

for j in my_range(1,10,2)
        print(j)

yield 表达式形式

yield支持外界为其传参

def dog(name):
  print('%s 准备开吃'%name)
      while  True:
            food = yield
            print('%s吃了%s' %(name,food))

当函数内有yield关键字的时候,调用该函数不会执行函数体代码。而是将函数变成生成器

g = dog('egon')

g.__next__()   必须先将代码运行至yield 才能够为其传值

g.send('包子')  给yield左边的变量传参  同时出发__next__()方法

yield
1.帮你提供了一种自定义生成器方式
2.会帮你将函数的运行状态暂停住
3.可以返回值

与return之间异同点
相同点:都可以返回值,并且都可以返回多个
不同点:
yield可以返回多次值,而return只能返回一次函数立即结束
yield还可以接受外部传入的值

生成器表达式

res = (i for i in range(1,100000000) if i != 4)
print(res)

生成器不会主动执行任何一行代码,必须通过__next__触发代码的运行(*********)

面向过程编程

面向过程编程:就类似于设计一条流水线

  好处:将复杂的问题流程化 从而简单化

  坏处:可扩展性较差  一但需要修改,整体都会受到影响

 

posted @ 2019-07-15 16:33  s686编程传  阅读(146)  评论(0编辑  收藏  举报