zoukankan      html  css  js  c++  java
  • 函数迭代器与生成器

    迭代器

    什么是迭代器?

      迭代:更新换代(重复)的过程,每次的迭代都必须基于上一次的结果

      迭代器:迭代取值的工具

    为什么要用?

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

    n = 0
    while True:
        print(n)
    #这就是不算是迭代器,只是简单的重复
    
    l = [1,2,3,4]
    s = 'hello'
    n = 0
    while n < len(s):
        print(n)
        n+=1
    #重复+每次迭代都是基于上一次的结果而来的

    需要迭代取值的数据类型:

      字符串

      列表

      元组

      字典

      集合

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

    基本数据类型中是可迭代的对象有:

      str    list    tuple  set   dict

      文件对象(执行内置的__iter__之后还是本身   没有任何变化):文件对象本身就是迭代器对象

    s = 'hello'
    l = [1,2,34,]
    t = (1,2,34)
    s1 = {1,2,3,4}
    d = {'name':'jason'}
    f1 = open('xxx.txt','w',encoding='utf-8')
    
    res = s.__iter__()  # res = iter(s)
    print(s.__len__())  # 简化成了len(s)
    res1 = l.__iter__()  # res1 = iter(l)
    res2 = f1.__iter__()  # res2 = iter(f1)
    print(res,res1,res2)
    print(f1)

    可迭代对象执行内置的__iter__方法得到就是该对象的迭代器对象

    迭代器的取值

    迭代器对象:

      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__())  #如果取完了  直接报错
    
    d = {'name':'yzy','sex':'male'}
    #将可迭代对象d转换成迭代器对象
    iter_d = d.__iter__()
    #迭代器对象的取值必须用__next__
    print(iter_d.__next__())
    print(iter_d.__next__())
    print(iter_d.__next__()) #取完了  报错StopIteration

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

    d = {'name':'jason','password':'123','hobby':'泡m'}
    iter_d = d.__iter__()
    
    #异常处理
    while True:
        try:
            print(iter.d__next__())
        except StopIteration:
            print('no')
            break
    d = {'name':'jason','password':'123','hobby':'泡m'}
    iter_d = d.__iter__()
    
    #异常处理
    while True:
        try:
            print(iter.d__next__())
        except StopIteration:
            print('no')
            break

    迭代器取值的特点:

      只能往后依次取,不能后退

    Ps:可迭代对象执行内置的__iter__方法得到的就是该对象的迭代器对象

    d = {'name':'jason','password':'123','hobby':'泡m'}
    for i  in d:
        print(i)
    #for循坏后面的in关键  跟的是一个可迭代对象
    

     for循坏内部的本质

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

      2.调用__next__迭代取值

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

    可迭代对象:内置有__iter__方法

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

    迭代取值:

      优点:

        1.不依赖与索引取值

        2.内存中永远只占一份空间,不会导致内存溢出

      缺点:

        1.不能够获取指定的元素

        2.取完之后会报StopIteration错

    生成器

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

     def func():
         print('first')
         yield  666  # 函数内如果有yield关键字,那么加括号执行函数的时候并不会触发函数体代码的运行
         print('second')
         yield  777
         print('third')
         yield  888
         print('forth')
         yield
         yield
    
    #yield 后面跟的值就是调用迭代器__next__方法你能得到的值
    #yield既可以返回一个值也可以返回多个值,并且多个值也是按照元组的形式返回
    g = func()#生成器初始化:将函数变成迭代器
    print(g)
    print(g.__next__())
    print(g.__next__())
    print(g.__next__())
    print(g.__next__())
    print(g.__next__())
    

    #yield支持外界为其传参

    def dog(name):
        print('%s 准备开吃'%name)
        while True:
            food = yield
            print('%s 吃了 %s'%(name,food))
    当函数内有yield关键字的时候,调用该函数不会执行函数体代码
    而是将函数变成生成器
    g = dog('yyy')
    g.__next__()  # 必须先将代码运行至yield 才能够为其传值
    g.send('apple')  # 给yield左边的变量传参  触发了__next__方法
    

    yield

      1.帮你提供了一种自定义生成器方式

      2.会帮你将函数的运行状态暂停

      3.可以返回值

    与return之间的异同点:

      相同点:都可以返回值,都可以返回多个

      不同点:

        yield可以返回多次值,而return只能返回一次函数立即结束

        yield还可以接受外部传入的值

    生成器表达式

    res = (i for i in range(1,100) if i != 4)  #生成器表达式
    
    #生成器不会主动执行任何一行代码,必须通过__next__触发代码的运行
    print(res.__next__())
    print(res.__next__())
    print(res.__next__())
    print(res.__next__())
    with open('name.txt','r',encoding='utf-8')as f:
        n = 0 
        for line in f:
            n += len(line)
        print(n)
    
    
    g = (len(line) for line in f)
    print(g.__next__())
    print(g.__next__())
    print(g.__next__())
    print(sum(g))

    常用的内置方法

    abs()#求绝对值

    abs(-1)

    print(bin(10))  #2进制
    print(oct(10))   #8进制
    print(hex(10))   #16进制 
    print(int('0b1010',2)    #将2进制转换成10进制
    
    callable()#判断是否可调用
    
    print(chr(97))#将数字转换成ascii码表对应的字符
    print(ord('a')) #将字符按照ascii表转成对应的数字
    
    dir 获取当前对象名称空间里面的名字
    l = [1,2,3]
    print(dir(l))
    
    divmod  分页器
    print(divmod(100,10))
    
    total_num,more = divmod(900,11)
    if more:
        total_num += 1
    print('总页数:',total_num)
    
    enumerate 枚举
    l = ['a','b']
    for i,j in enumerate(l,1):
        print(i,j)
    
    eval exec
    s = """
    print('hello baby')
    x = 1
    y = 2
    print(x+y)
    """
    eval(s)
    exec(s)
    #eval 不支持逻辑代码,只支持一些简单的python代码
    
    isinstance  判断对象是否属于某个数据类型
    n = 1
    print(inistance(n,int))
    
    pow
    print(pow(2,3))  #8
    
    round
    print(round(3.4))   # 3
    print(round(3.6))    #4

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

      好处:

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

      坏处:

        可扩展性较差  一旦需要修改   整体都会受到影响

  • 相关阅读:
    MySQL多表查询
    多表关联
    MySQL数据类型 约束
    初识数据库
    socker server和 event
    os 模块 和 os模块下的path模块
    sys 模块
    time 模块
    目录规范

  • 原文地址:https://www.cnblogs.com/KrisYzy/p/11190156.html
Copyright © 2011-2022 走看看