zoukankan      html  css  js  c++  java
  • Python之生成器及内置函数篇4

    一、可迭代对象

    #1、什么是迭代?:迭代是一个重复的过程,并且每次重复都是基于上一次的结果而来
    #2、可迭代的对象:在python中,但凡内置有__iter__方法的对象,都是可迭代的对象
    #3、迭代器:迭代取值工具,可迭代的对象执行__iter__方法得到的返回值就是迭代器对象
    #4、可迭代的对象:str,list,tuple,dict,set,file
      获取可迭代对象的方式:无须获取,python内置str,list,tuple,dict,set,file都是可迭代对象
      特点:
    	内置有__iter__方法的都叫可迭代的对象,执行该方法会拿到一个迭代器对象
    #5、迭代器对象:文件对象本身就是迭代器对象
      1、获取迭代器对象的方式:
    	执行可迭代对象的__iter__方法,拿到的返回值就是迭代器对象
      2、特点:
    	内置有__next__方法,执行该方法会拿到迭代器对象中的一个值
    	内置有__iter__方法,执行该方法会拿到迭代器本身
    		
    #6. for循环原理分析:
      1、for 循环称之为迭代器循环,in后跟的必须是可迭代的对象
      2、for循环会执行in后对象的__iter__方法,拿到迭代器对象
      3、然后调用迭代器对象的__next__方法,拿到一个返回值赋值给line,执行一次循环体
      4、周而复始,直到取值完毕,for循环会检测到异常自动结束循环
    

    1)迭代器的例子

    list1=[1,2,3]
    iter_list1=list1.__iter__()
    print(iter_list1.__next__())
    print(iter_list1.__next__())
    print(iter_list1.__next__())

    2)文件也是可迭代对象

    l=open('a.txt','r',encoding='utf-8')
    iter_l=l.__iter__()
    while True:
        try:
            print(iter_l.__next__())
        except StopIteration:
            break
    

    二、生成器或迭代器的使用

    生成器:
    函数内包含有yield关键字,
    再调用函数,就不会执行函数体代码,拿到的返回值就是一个生成器对象
    
    总结yield:
    1、为我们提供了一种自定义迭代器的方式,
       可以在函数内用yield关键字,调用函数拿到的结果就是一个生成器,生成器就是迭代器
    2、yield可以像return一样用于返回值,区别是return只能返回一次值,而yield可返回多次
       因为yield可以保存函数执行的状态
    

    1)迭代器的使用

    def chicken():
        print('=====>first')
        yield 1
        print('=====>sencond')
        yield 2
        print('=====>third')
        yield 3
    
    obj=chicken()
    print(obj)
    # 生成器本质就是迭代器,也就是说生成器的玩法其实就是迭代器的玩法
    print(obj.__iter__() is obj)
    res1=obj.__next__()
    print(res1)
    
    res2=obj.__next__()
    print(res2)
    
    res3=next(obj)  # 简写
    print(res3)
    View Code

    2)用生成器造成无穷多的数

    def my_range():
        print('start........')
        n=0
        while True:
            yield n
            n+=1
    
    obj=my_range()
    
    print(obj.__next__())
    print(obj.__next__())
    print(obj.__next__())
    print(obj.__next__())
    
    for i in my_range():
        print(i)
    View Code

    3)创造一个自己的range

    def my_range(start,stop,step=1):
        n=start
        while n < stop:
            yield n #yield 4
            n+=step #5
    
    
    obj=my_range(3,7,2) #3,5,
    print(obj.__next__())
    print(obj.__next__())
    View Code

     4) yield传值使用

    def eat(name):
        print('%s ready to eat' %name)
        food_list=[]
        while True:
            food=yield food_list
            food_list.append(food)
            print('%s start to eat %s' %(name,food))
    
    dog1=eat('user')
    #1、必须初始化一次,让函数停在yield的位置
    res0=dog1.__next__()
    print(res0)
    
    #2、接下来的事,就是喂狗
    #send有两方面的功能
    #1、给yield传值
    #2、同__next__的功能
    res1=dog1.send('泔水')
    print(res1)
    res2=dog1.send('骨头')
    print(res2)
    res3=dog1.send('shit')
    print(res3)
    View Code

     三、三元表达式

      把一个简单的普通的函数变成了一行代码,即三元表达式

    def max2(x,y):
        if x > y:
            return x
        else:
            return y
    res=max2(10,11)
    print(res)
    x=12
    y=11
    
    #三元表达式仅应用于:
    #1、条件成立返回 一个值
    #2、条件不成立返回 一个值
    # res=x if x > y else y
    # print(res)
    def max2(x,y):
        return x 
    View Code

     四、函数递归

    1)设置递归限制次数

    #函数递归:函数的递归调用,即在函数调用的过程中,又直接或间接地调用了函数本身
    import sys
    print(sys.getrecursionlimit())
    sys.setrecursionlimit(10000)
    print(sys.getrecursionlimit())

    2)函数递归调用的例子

    # 直接调用
    def foo():
        print('from foo')
        foo()
    foo()
    
    # 间接调用
    def bar():
        print('from bar')
        foo()
    def foo():
        print('from foo')
        bar()
    foo()
    View Code

    3)递归的概念

    # 递归分为两个阶段
    #1、回溯:
        # 注意:一定要在满足某种条件结束回溯,否则的无限递归
    #2、递推
    
    # 总结:
    #1、递归一定要有一个明确地结束条件
    #2、没进入下一次递归,问题的规模都应该减少
    #3、在python中没有尾递归优化

    4)递归小高潮,age(n-1)+2

    def age(n):
        if n == 1:
            return 18
        return age(n-1)+2 #age(4)+2
    # 分析
    # age1 = 18
    # age2 = 20
    # age3 = 22
    # age4 = 24
    # age5 = 26
    print(age(5))
    View Code

    5)递归特殊列表打印

    items=[1,[2,[3,[4,[5,[6,[7,[8,[9,[10,]]]]]]]]]]
    def tell(l):
        for item in l:
            if type(item) is not list:
                print(item)
            else:
                tell(item)
    
    tell(items)
    View Code

    五、匿名函数,lambda

    # 有名函数
    def foo(x,n):
        return x ** n
    # ====》匿名函数
    f=lambda x,n:x ** n
    print(f(2,3))
    print(f(2,4))
    

    1)强调注意点

    1 匿名的目的就是要没有名字,给匿名函数赋给一个名字是没有意义的。也就是使用一次
    2 匿名函数的参数规则、作用域关系与有名函数是一样的
    3 匿名函数的函数体通常应该是 一个表达式,该表达式必须要有一个返回值
    

    2)匿名函数的应用

    练习一,找出下面工资最高人,提示,max

    salaries={
        'zhangsan':3000,
        'lisi':1000,
        'Mr.C':10000,
        'Tina':5000
    }
    
    salaries={
        'zhangsan':3000,
        'lisi':1000,
        'Mr.C':10000,
        'Tina':5000
    }
    print(max(salaries,key=lambda x:salaries[x]))
    View Code

    相应的求工资工资最低的那个人

    print(min(salaries,key=lambda x:salaries[x]))
    View Code

    按照工资的高低顺序排列

    salaries1=sorted(salaries,key=lambda x:salaries[x])  #默认是升序排
    salaries2=sorted(salaries,key=lambda x:salaries[x],reverse=True) #降序
    print(salaries1)
    print(salaries2)
    View Code

    练习二,map,映射关系

     将列表变成成 [1,4,9,16,25]

    nums=[1,2,3,4,5]
    nums=[1,2,3,4,5]
    res=map(lambda x:x**2,nums)
    print(list(res))
    View Code
    将列表['zhangsan','lisi','Tina']中的所有元素加上"_SB"
    names=['zhangsan','lisi','Tina']
    res=map(lambda x:x+'_SB',names)
    print(list(res))
    View Code
    之上升级需求['zhangsan','lisi','Tina','lufei'],除了'lufei'加"_NB"外,其他加"_SB"
    names=['zhangsan','lisi','Tina','lufei']
    res=map(lambda x:x+'_NB' if x == 'lufei' else x + '_SB',names)
    print(list(res))
    View Code

    练习三,reduce,合并

    求1+2+3+4......99+100的和

    from functools import reduce
    res1=reduce(lambda x,y:x+y,range(1,101),100)  # 出始值是100
    res2=reduce(lambda x,y:x+y,range(1,101))      # 默认初始值是0
    print(res1)
    View Code

    字符串拼接

    l=['my','name','is','god']
    res=reduce(lambda x,y:x+' '+y,l,'Oh,')
    print(res)
    View Code

    练习四,过滤 filter

    ['zhangsan_sb','lisi_nb','Tina_sb','lufei_nb']过滤出后面是sb的人
    names=['zhangsan_sb','lisi_sb','Tina_sb','lufei_nb']
    # res1=filter(lambda x:True if x.endswith('sb') else False,names)  # 画蛇添足
    res2=filter(lambda x:x.endswith('sb'),names)
    print(list(res2))
    View Code
    过滤出工资大于4000的
    salaries={
        'zhangsan':3000,
        'lisi':1000,
        'Mr.C':8000,
        'Tina':5000
    }
    res=filter(lambda k:salaries[k] >= 4000,salaries)
    print(list(res))
    View Code

    六、生成式与生成器表达式

    1)列表生成式

    列表生成器基本操作
    l=['egg%s' %i for i in range(10)]
    print(l)
    
    ll=('egg%s' %i for i in range(10))  # 节约内存
    print(ll)
    print(list(ll))
    
    nums=[i**2 for i in range(10) if i > 3]
    print(nums)
    View Code
    将names=['zhangsan','lisi_sb','wudalang','tangsan']中的名字全部变大写
    names=['zhangsan','lisi_sb','wudalang','tangsan']
    names=[name.upper() for name in names]
    print(names)
    View Code
    将names=['zhangsan','lisi_sb','wudalang','tangsan']中以sb结尾的名字过滤掉,然后保存剩下的名字长度
    names=['zhangsan','lisi_sb','wudalang','tangsan']
    l=[len(name) for name in names if not name.endswith('sb')]
    print(l)
    View Code

    2)字典生成式

    d={'user%i'%i:i for i in range(10) if i > 0}
    print(d)
    
    userinfo=[('egon','123'),('alex','456'),('wxx','679')]
    dic={k:v for k,v in userinfo}
    print(dic)
    View Code

     3)生成器表达式

    g=(i for i in range(10))
    print(g)
    print(next(g))
    print(next(g))
    print(next(g))
    
    chicken=('egg%s' %i for i in range(3))
    # print(chicken)
    print(next(chicken))
    print(next(chicken))
    print(next(chicken))
    
    with open('a.txt','r',encoding='utf-8') as f:
        nums=(len(line) for line in f)
        # print(nums)
    # print(nums)
    # print(next(nums))
    print(max(nums))
    View Code

    强调:()和[] 的区别

    七、import导入模块

    1)如何导入模块

    # 导入模块方式一
    import spam
    import spam as sm
    # 使用方法
    spam.read1()
    
    # 导入模块方式二
    # from spam import money,read1,read2,change
    # from spam import *
    # 使用方法
    read1()
    View Code

    注意点,对于from spam import *,*指所有,也可对*进行控制

    __all__=['money','read1']   # from spam import *,控制的就是*所导入的名字
    View Code

    2)定义模块的调试,避免到导入时执行调试的代码

    # 当文件被当做脚本执行时__name__的值为"__main__"
    # 当文件被导入时__name__的值为"模块名"
    # print(__name__)
    # main()可快速写成__name__ == '__main__'
    if __name__ == '__main__': # 改行代码用于区分python文件的两种不同用途,应该写在文件末尾
        read1()
        read2()
        change()
    View Code

    3)模块之间嵌套导入

    1、尽可能的避免嵌套导入模块
    2、导入的模块,放入最后或执行函数导入
    View Code

     4)不在同级目录下的导入

    # 方法一,加路径
    import sys
    sys.path.append(r'D:oldboyedumanth-02day-01dir')
    print(sys.path)  # sys.path是以当前执行文件为准的路径
    import spam
    # 方法二,在同级目录的子集
    from dir import spam
    from dir1.dir2 import spam # 在同级目录的孙集
    View Code

    5)在被导入的模块中再导入别人模块

    from . import m2   # 从当前路径寻找其他模块
    from .. import m2  # 从上层路径寻找其他模块
    View Code
  • 相关阅读:
    第四阶段学习总结
    第三阶段学习总结
    第二阶段学习总结
    第一阶段内容的学习总结
    第四单元及OO课程总结
    关于工具的碎碎念
    第三单元博客总结
    第二单元博客总结
    第一单元作业总结
    实验五 单元测试
  • 原文地址:https://www.cnblogs.com/linu/p/8978777.html
Copyright © 2011-2022 走看看