zoukankan      html  css  js  c++  java
  • python学习Day15 生成器send方法、递归、匿名函数、内置函数

    复习

    1.带参装饰器 - 自定义 | wraps  

      通过外界对内部函数传参,可以对一个功能进行二选一选择某一个功能进行装饰。

      @warap('1')  ===>  执行wrap('1')先得到@outer 【当有()时,优先执行小(),括号有优先权】

    2.可迭代对象:有__iter__()方法的对象,并且调用__iter__()方法得到迭代器对象

    3. 迭代器对象:有__next__()方法的对象,并且调用__next__()方法从前往后逐一取值不依赖索引取值,但必须从前往后依次取值(无法获取索引,也无法计算长度)】

    4. for循环迭代器工作原理

    1)得到操作对象的迭代器对象
    2)通过__next__()进行取值
    3)自动处理StopIteration异常,结束循环

    5.枚举对象:为被迭代的对象添加迭代索引 -- enumerate

    6.生成器: 语法同函数,内部包含yield关键字,函数名() 不是函数调用,而是得到生成器对象 --> 就是自定义的迭代器对象

    今日内容

    1.生成器的send方法          2.递归:函数增加某种规律后自己调自己本身          3.匿名函数:lambda              4.内置函数

    1. 生成器的send工作原理

        1) send 送出信息给当前停止的yield      2) 再去调用__next__()方法,生成器接着往下指向,返回下一个yield值并停止

       

    2. 递归 :函数直接或间接调用本身,都称之为递归

    回溯:找寻答案的过程, --溯源
    递推:推出结果的过程 

    前提条件:1.递归必须有出口   |      2.递归回溯递推的条件一定有规律

    案例一:获得第 count 个人的年纪:

               def get_age(count):

                      if count == 1:
                              return 58
                     # 第 九...一 个人 - 2
                      age = get_age(count - 1) - 2
                      return age

               age = get_age(3)
               print(age)

    案例二:求n的阶乘   5!= 5 * 4 * 3 * 2 * 1:

    5! = 5 * 4!

    4!= 4 * 3!

    3!= 3 * 2!

    2!= 2 * 1!

    1!= 1

    def  jicheng(n):

            if n == 1 or n == 0:

                    return 1

            ji  = n * jiecheng(n-1)

            return  ji

    res = jiecheng(5)

    print(res)

    3.匿名函数  :   lambda *args, **kwargs: '返回值'

    用一次,不会二次调用

    1).匿名函数没有函数名
    2).匿名函数的关键字采用lambda
    3).关键字 lambda 与标识函数功能体 : 之间一定是参数,所以省略()
    4).匿名还是没有函数体,只有返回值,所以函数体和返回值的return关键字都省略了

    注意:
    1.参数的使用和有名函数一样,六种形参都支持
     2.返回值必须明确成一个值,可以为单个值对象,也可以为一个容器对象

    a = lambda *args, **kwargs: '返回值1', '返回值2'
    print(a)     # (<function <lambda> at 0x0000022D0B7E88C8>, '返回值2')
    print(a[0]())   #返回值1

    正确返回两个值: 主动构成成容器类型: lambda *args, **kwargs: ('返回值1', '返回值2')

    3.2匿名函数工作原理(结合内置函数):

    max(iter, key=fn) 

    # 可以通过max函数的key参数来改变max函数的比较依据,运行原理:

    # max 函数会“ for 循环” 出一个值,然后将该值传给指定的fn函数

    #调用key指定的函数,将拿到的返回值当作比较依据

    salaries ={
    'egon': 30000,
    'alex': 10000000,
    'wupeiqi':10000,
    'yuanhao': 2000
    }

    def func(name):

            return salaries[name]

    max(salaries, key=func)

    用lambda来写

    1) max(salaries, key= lambda x:salaries[x])  #求大值

    2) min(salaries, key= lambda x:salaries[x])   #求小值,原理同max

    3) sorted   #排序,产生一个新列表, reverse默认False

         nums = [11, 33, 22, 9, 31]

         res = sorted(nums)    # [9, 11, 22, 31, 33]

        res = sorted(nums, reverse= True)   #从到小, 默认reverse = False ,从小到大

       

    #求按薪资从小到大排序的人名
    salaries ={
    'egon': 30000,
    'alex': 10000000,
    'wupeiqi':10000,
    'yuanhao': 2000
    }
    res =sorted(salaries, key=lambda x: salaries[x])
    print(res) #['yuanhao', 'wupeiqi', 'egon', 'alex']

    例 :res列表中依每个字典的tid中的值排序

    res = [{'tid': 1, 'tname': 'zekai', 'cname': '脱产7期', 'cid': 1},
    {'tid': 3, 'tname': 'Tank', 'cname': '脱产7期', 'cid': 1},
    {'tid': 4, 'tname': 'jason', 'cname': '脱产7期', 'cid': 1},
    {'tid': 1, 'tname': 'zekai', 'cname': '脱产8期', 'cid': 2},
    {'tid': 2, 'tname': 'egon', 'cname': '脱产8期', 'cid': 2},
    {'tid': 3, 'tname': 'Tank', 'cname': '脱产8期', 'cid': 2},
    {'tid': 2, 'tname': 'egon', 'cname': '脱产9期', 'cid': 3},
    {'tid': 3, 'tname': 'Tank', 'cname': '脱产9期', 'cid': 3},
    {'tid': 3, 'tname': 'Tank', 'cname': '脱产10期', 'cid': 4},
    {'tid': 4, 'tname': 'jason', 'cname': '脱产10期', 'cid': 4}]

    res1 = sorted(res, key=lambda x: x['tid']) ==> 匿名函数中的x为sorted循环后得到的一个元素,即里面的一个个的字典,将这些字典以传参的形式交给lambda函数,
                                 lambda函数体中是排序的逻辑【条件】,如左例中res排序,条件:以字典的tid大小进行排序。
    output:

    res1 = [{'tid': 1, 'tname': 'zekai', 'cname': '脱产7期', 'cid': 1},
        {'tid': 1, 'tname': 'zekai', 'cname': '脱产8期', 'cid': 2},
        {'tid': 2, 'tname': 'egon', 'cname': '脱产8期', 'cid': 2},
        {'tid': 2, 'tname': 'egon', 'cname': '脱产9期', 'cid': 3},
        {'tid': 3, 'tname': 'Tank', 'cname': '脱产7期', 'cid': 1},
        {'tid': 3, 'tname': 'Tank', 'cname': '脱产8期', 'cid': 2},
        {'tid': 3, 'tname': 'Tank', 'cname': '脱产9期', 'cid': 3},
        {'tid': 3, 'tname': 'Tank', 'cname': '脱产10期', 'cid': 4},
        {'tid': 4, 'tname': 'jason', 'cname': '脱产7期', 'cid': 1},
        {'tid': 4, 'tname': 'jason', 'cname': '脱产10期', 'cid': 4}]

       4)map<映射> , filter<过滤>, reduce

         map 映射, 工作原理类同max:

          map 函数会“ for 循环” 出一个值,然后将该值传给指定的fn函数

          调用函数fn,将拿到的返回值当作映射的逻辑结果

    names = ['alex', 'lxx', 'wxx', 'yxx']
    res = map(lambda name:name + '_SB', names)
    print(res) # 得到一个生成器地址 <map object at 0x000001E54C32B3C8>
    print(list(res)) # ['alex_SB', 'lxx_SB', 'wxx_SB', 'yxx_SB']

    5)filter 过滤, 工作原理类同max:相当于for 循环取出每一个人名,然后传给匿名函数,将调用匿名函数返回值为True的那个人名留下来
    filter(function, iterable)
    names = ['alex_sb', 'lxx_sb', 'wxx_sb', 'yxx']

    res = filter(lambda x: x.endswith('sb'), names)
    print(list(res))  # ['alex_sb', 'lxx_sb', 'wxx_sb']
    也可直接用列表推导式:res =[name for name in names if name.endswith('sb')]
    6)reduce: 把多个值合并成一个结果,两两相加:
    reduce(function, iter) 注:from functools import reduce
    例1: ls = ['a', 'b', 'c', 'd']
    res = reduce(lambda x, y: x + y, ls, )
    print(res) # abcd

    例2:ls = ['a', 'b', 'c', 'd']
    res = reduce(lambda x, y: x + y, ls, 'A' )
    #'A', 'a' => 'Aa'

    #'Aa', 'b' => 'Aab'
    #'Aab', 'c'  => 'Aabc'
    #'Aabc', 'd'  => 'Aabcd'
    print(res)  # Aabcd
    例3:从1加到100:
    res = reduce(lambda x, y:x + y, range(1, 101))
    print(res)


  • 相关阅读:
    SqlServer卸载实例
    java写的各种钟(收集)
    Codeforces 1003D Coins and Queries 【性质】
    Codeforces 997B Roman Digits【暴力】【枚举】
    洛谷 P2679 子串 【dp神题】【滚动数组】【2015 noip d2t2】
    复习图论
    Codeforces 1000D Yet Another Problem On a Subsequence 【dp】【组合数学】
    Codeforces 1000C Covered Points Count 【前缀和优化】
    Codeforces 999F Cards and Joy 【dp】【性质】
    Codeforces 999D Equalize the Remainders 【模拟】
  • 原文地址:https://www.cnblogs.com/qingqinxu/p/10796943.html
Copyright © 2011-2022 走看看