• 匿存函数,内存函数,递归函数,二分法查找


    一.匿名函数(lambda)

    语法:  lambda  参数: 返回值

    函数名统一都叫lambda

    1.把普通函数转换成匿名函数

    def func(n)
        return n * n
    ret = func(9)
    print(ret)
    普通
    a = lambda n: n * n
    ret = a(9)
    print(ret)
    匿名

    其中a可以认为是函数名,但是在__name__中函数名统一是lambda

    print(func.__name__)  #查看函数名
    print(a.__name__)       #__name__的值都是<lambda>
    查看函数名
    def func(a, b)
        return a + b
    
    x = lambda a, b : a+b
    print(x(a , b))
    两个参数的匿名函数
    def func(x, y)
        return x, y
    
    s = lambda x, y :(x, y)#如果不放(),s会被分为两部分 lambda x, y :x和y
    print(s(250, 38))
    两个返回值的匿名函数
    fn = lambda *args :max(args) #匿名函数一定是一行函数
    print(fn(1,3,8,56))#56
    求最大值

    二.sorted()  排序函数

    语法:sorted(iterable, key, reverse)

    key:排序规则.

    运行流程: 把可迭代的对象中是每一个元素交给后面的key函数来执行.

        得到一个数字(权重).通过这个数字进行排序

    lst = ["聊斋", "西游记", "三国演义", "葫芦娃", "水浒传", "年轮", "亮剑"]
    def func(s)
        return len(s)
    li = sorted(lst, key = func)
    print(li)
    #key: 排序方案, sorted函数内部会把可迭代对象中的每一个元素拿出来交给#后面的key,后面的key计算出一个数字. 作为当前这个元素的权重, 整个函根
    #据权重进行排序
    根据字数排列
    lst = [
        {'name':"汪峰","age":48},
        {"name":"章子怡",'age':38},
        {"name":"alex","age":39},
        {"name":"wusir","age":32},
        {"name":"赵一宁","age":28}
        ]
    
    ll = sorted(lst, key=lambda el: len(el['name']), reverse=True)
    print(ll)
    View Code

    三.filter() 过滤函数

    语法:     filter(function, iterable)

    运行流程;把可迭代对象中的数据交给前面的函数进行筛选.函数返回True或者False

    #普通函数
    lst = ["张无忌", "张铁林", "赵一宁", "石可心","马大帅"]
    def func(el)
        if el[0] == ""
            return False  #不想要的
        else:
            return True  #想要的
    f = filter(func, lst)
    print("__iter__" in dir(f)) # 判断是否可以进行迭代
    for e in f:
         print(e)
    
    #匿名函数
    f = filter(lambda el :el[0] != "", lst)
    print("__iter__" in dir(f)) # 判断是否可以进行迭代
    for e in f:
         print(e)
    排除姓张的人
     lst = [
         {"name":"汪峰", "score":48},
         {"name":"章子怡", "score":39},
         {"name":"赵一宁","score":97},
         {"name":"石可心","score":90}
     ]
    
     f = filter(lambda el: el['score'] < 60 , lst) # 去16期的人
    
     print(list(f))
    求分数小于60的

    四.map()     映射函数

    语法:  把可迭代对象中的数据交给前面的函数进行执行,返回值就是map()的处理结果

    lst = [1,4,7,2,5,8]
    li = []
    #第一种方法:算法
    for el in lst:
        li.append(el**2)
    #第二种方法:普通函数
    def func(el)
        return el**2
    m = map(func, lst)
    print(list(m))
    #第三种方法:匿名函数
    m = map(lambda el: el**2, lst)
    print(list(m))
    # 把后面的可迭代对象中的每一个元素传递给function, 结果就是function返
    #回值
    计算列表中每个数字的平方
    map(func1, map(func2, map(func3 , lst)))
    分而治之
    map(func1, map(func2, map(func3 , lst)))
    当我们处理的数据过大时可以用分而治之的思想(如人工智能中的数据处理)

    五.递归函数(默认递归函数是死循环)

    1.定义:函数自己调用自己

    2.递归函数的深度: 1000. 到不了1000就会停止(深度可以自己设置)

    import sys
    sys.setrecursionlimit()
    深度
    count = 1
    def func():
        global count
        print("alex是很帅的", count)
        count = count + 1
        func()
    func()

    递归深度. 你可以自己掉用自己的次数,官方文档中递归最大深度是1000. 在这之前就会给你报错

    3.递归函数的用处

    3.1处理相似的操作

    # 遍历 D:/sylar文件夹, 打印出所有的文件和普通文件的文件名
    import os
    def func(filepath, n): # d:/sylar/
         # 1,打开这个文件夹
         files = os.listdir(filepath)
         # 2. 拿到每一个文件名
         for file in files:  # 文件名
             # 3. 获取到路径
            f_d = os.path.join(filepath, file) # d:/sylar/文件名/
             # 4. 判断是否是文件夹
            if os.path.isdir(f_d):
                 # 5. 如果是文件夹. 继续再来一遍
                 print("	"*n, file,":") # 打印文件名
                 func(f_d, n + 1)
            else:   #  不是文件夹. 普通文件
                print("	"*n, file)
    
     func("d:/sylar",0)
    遍历文件

    3.2传播病毒(要在每个文件夹下的每个文件投放病毒)

    3.3杀毒

    3.4求阶乘

    def func(n,s):    #计算n的阶乘
        if n > 0:
            s = n * s
            n = n - 1
            return func(n,s)
        else:
            return s
    ret = func(8,1)
    print(ret)
    阶乘

    3.5斐波那契(如计算第400个数,  不超过4000000(400万)最多计算几次)

    def func(n,i,a,b):#a第一个数,b第二个数,i是第几次计算
        c = a + b # 第三个数
        if n > i:
            a = b
            b = c
            i+=1
            return func(n,i,a,b )
        else:
            return c
    ret = func(400,3,1,1)
    print(ret)
    View Code
    def func(n,i,a,b):#a第一个数,b第二个数,i是第几次计算
        c = a + b # 第三个数
        if n > c:
            a = b
            b = c
            i+=1
            return func(n,i,a,b )
        else:
            return i
    ret = func(4000000,3,1,1)
    print(ret)
    计算几次

    4.递归函数中的return 返回值,返回给上一层调用者

    六.二分法

    1.二分法的核心: 掐头去尾取中间,一次砍一半

    2.两种算法:常规循环,递归循环

     lst = [22, 33, 44, 55, 66, 77, 88, 99, 101 , 238 , 345 , 456 , 567 , 678 , 789 ]
    n = 79
    
    for el in lst:
         if el == n: # O(1)
            print("找到了")
            break
    else:
        print("没有")
    View Code
    使用二分法可以提高效率, 前提条件:有序序列
    lst = [22, 33, 44, 55, 66, 77, 88, 99, 101 , 238 , 345 , 456 , 567 , 678 , 789]
    n = 88
    left = 0
    right = len(lst)-1
    while left <= right: # 边界, 当右边比左边还小的时候退出循环
        mid = (left + right)//2 # 必须是整除. 因为索引没有小数
        if lst[mid] > n:
            right = mid - 1
        if lst[mid] < n:
            left = mid + 1
        if lst[mid] == n:
            print("找到了这个数")
            break
    else:
         print("没有这个数")
    二分法查找
    lst = [22, 33, 44, 55, 66, 77, 88, 99, 101 , 238 , 345 , 456 , 567 , 678 , 789]
    def func(n, left, right):
        if left <= right: # 边界
            print("哈哈")
            mid = (left + right)//2
            if n > lst[mid]:
                left = mid + 1
                return func(n, left, right) # 递归  递归的入口
            elif n < lst[mid]:
                right = mid - 1
                # 深坑. 函数的返回值返回给调用者
                return func(n, left, right)    # 递归
            elif n == lst[mid]:
                print("找到了")
                return mid
                # return  # 通过return返回. 终止递归
        else:
            print("没有这个数") # 递归的出口
            return -1 # 1, 索引+ 2, 什么都不返回, None
    # 找66, 左边界:0,  右边界是:len(lst) - 1
    ret = func(70, 0, len(lst) - 1)
    print(ret) # 不是None
    递归完成二分查找
    def binary_search(ls, target):
     left = 0
     right = len(ls) - 1
     if left > right:
     print("不在这里")
     middle = (left + right) // 2
     if target < ls[middle]:
     return binary_search(ls[:middle], target)
     elif target > ls[middle]:
     return binary_search(ls[middle+1:], target)
     else:
     print("在这里")
    binary_search(lst, 567)
    切片二分法

    切片二分法很难确定位置

    3.给一x位数,2**n    最多要查找n次  时间复杂度 o(1)~o(n)

    七.最快速的查询讯方式(时间复杂度最低,空间复杂度最低)

      查询某个元素是否在某个序列中

    lst1 = [5,6,7,8]

    lst2 = [0,0,0,0,0,0,0,0,0]  #9个0

    for el in lst1:

      lst2[el] = 1

    o(1) #时间复杂度是1

    解释: 查询某列表中lst是否存在某个元素a,

      1.先建立一个列表,列表中有lst中最大值加1个零

      2.当lst2[a] == 1是该元素存在列表中,当lst2[a]==0时该元素不存在列表中

    八总结

    filter()和map()一样得到的是地址,需要遍历才能得到结果

  • 相关阅读:
    面向对象知识点2
    面向对象知识点1
    面向对象知识点
    常用模块
    模块与包
    迭代器相关知识
    jquery.jqprint-0.3.js打印功能 以及页眉页脚设置显示与否
    js和layerjs配合实现的拖拽表格列
    iframe中跳转页面的区别
    select3搜索下拉树
  • 原文地址:https://www.cnblogs.com/Bug66/p/9482460.html
Copyright © 2020-2023  润新知