• day014 lambda函数,递归函数、二分法(3种)


    本节主要内容

    1.lambda函数  匿名函数
    2.sorted()  排序函数
    3.filter()  筛选函数
    4.map() 映射函数
    5.递归函数 (自己调用自己)
    6.二分法  (掐头去尾取中间)

    一、lambda 匿名函数

    • 只适用于一些简单的需求的设计,一句话函数

    1、语法:

    函数名 = lambda 参数: 返回值

    注意:

    1.函数的参数可以有多个,多个参数用逗号隔开
    2.匿名函数不管多复杂,只能写一行,且逻辑结束后直接返回数据
    3.返回值和正常函数一样,可以是任何数据
    4.匿名函数不是没有名字,指的是匿名的意思是通过__name__查看时是没有名字的,统一叫lambda

    fe:写法和多个参数的示例

    a = lambda n: n**n # 匿名函数, 一般不会用来做复杂的操作
    r = a(3)
    print(r)
    
    print(a.__name__) # <lambda> 匿名函数有名字. 统一叫lambda
    
    # 写一个lambda 给函数传递两个参数, a, b 计算a+b的结果
    a = lambda m, n: m + n
    
    # 写一个lambda 计算字符串长度并返回 # len()
    a = lambda s: len(s)

    二、sorted() 排序函数

    语法:

    sorted(Iterable, key = None, reverse = False)
    Iterable: 可迭代对象
    key: 排序规则(函数),sorted内部会将可迭代对象的每一个元素传递个这个函数作为参数,根据函数的运算结果进行排序
    reverse: 是否倒叙, True: 倒叙; False: 正序

    fe:根据key里面的函数进行排序

    lst = ["易", "贾克斯", "赵信", "德玛西亚", "皇子", "刀妹"]
    # 按照文字的长短来排序
    def func(s):
        return len(s)
    
    s = sorted(lst, key=func) # 把列表中的每一个元素传递给func. 根据func返回值进行排序
    print(s)

    fe2: 根据字典里面的年龄,进行排序

    lst=[{'id':3,'name':'taihei','age':18},
         {'id':1,'name':'alex','age':28},
    {'id':2,'name':'taibai','age':58},
    
    {'id':4,'name':'henhei','age':38}]
    
    # 根据年龄排序
    def func(s):
        return s['age']
    
    print(sorted(lst, key=lambda dic:dic["age"])) # 根据年龄排序

    三、filter() 筛选函数

    语法:

    filter(function, Iterable)
    function: 用来筛选的函数。 在filter中会自动的把Iterable中的元素传递给function,然后根据function
    返回的True;则保存,否者,则去掉。
    Iterable: 可迭代对象

    fe: 根据function返回的True或False,来保存数据

    lst = ["渴望", "年轮", "家有儿女", "蜗居", "49天", "浪漫满屋"]
    
    #  把后面的可迭代对象中的每一个元素交给前面的函数。 根据函数返回的True或者False。 判断是否保留该元素
    f = filter(lambda s: len(s) > 2, lst)
    print("__iter__" in dir(f))
    for el in f:
        print(el)
    
    
    lst=[{'id':3,'name':'taihei','age':18},
         {'id':1,'name':'alex','age':28},
         {'id':2,'name':'taibai','age':58},
         {'id':4,'name':'henhei','age':38}]
    
    # 筛选年龄大于等于38的人
    print(list(filter(lambda ren: ren['age']>=38, lst)))

    四、map() 映射函数

    语法:

    map(function, Iterable)
    对可迭代对象中的每一个元素进行映射,分别执行function操作,返回新的迭代对象,需要变量接收它(新的)

    fe: 对旧的可迭代对象,执行function后,全部接收,返回新的

    lst = [2, 3, 4 ,5, 6, 7, 1]
    # 计算列表中的每一项的平方
    
    # 映射
    # 把可迭代对象中的每一个元素拿出来交给前面的函数执行. 保留最后的执行结果
    m = map(lambda x: x*x, lst)
    for el in m:
        print(el)
    
    # 给出一个列表
    lst = ["alex_123", "alex_456", "wusir_123", "wusir_456", "alex_789"]
    #
    # 正确的用户名: alex
    # 密码:456
    # alex_456
    # 第一种方法
    print(list(map(lambda s : " yes" if s=="alex_456" else "false"  , lst)))
    
    # 第二种方法
    print(list(map(lambda s: s.split("_")[0] == 'alex' and s.split("_")[1] == "456",lst)))

    五、递归(函数自己调用自己,缺点占内存)

    • 在函数中调用函数本身,就是递归

    • python中最大的递归深度为1000,但实际操作中不会让你到达1000,

    • 每递归一次就要开辟一片新的一模一样的内存空间,非常占内存,增加了空间复杂度,不能用于复杂的算法

    • 由第三点可以得出,当递归有返回值时,需要写return,传递最终返回值. 否则有可能接收不到返回值(因为函数的返回值是返回给调用者)

    fe:遍历文件夹的所有文件,及打印所有文件名(非文件夹的名字)

    import os
    
    def func(path, ceng):  # path传绝对路径,层用缩进来体现文件夹的所属关系(父子级),
        lst = os.listdir(path)  # os.listdir(路径) 打开文件夹获取所有的所有内容(所有的文件名含文件夹名字)
        for el in lst:  # 当前文件夹的所有文件名(包括文件夹名字)
            # 拼接真实路径
            file_real_path = os.path.join(path, el) # os.path.join(路径, 文件名) 拼接路径和文件名, 使得可以使用这个文件名
    
            if os.path.isdir(file_real_path):  # os.path.isdir(拼接好的路径和文件名的变量) 判断是文件夹还是文件
                # 递归的入口
                print("	" * ceng, el)
                func(file_real_path, ceng + 1) # 重复刚才的操作
    
    
            else:  # 不是文件夹,是文件
                #递归的出口
                print("	" * ceng, el)
    
    func(r"E:a", 0)

    5.1 操作系统(os)相关的一些操作

    os : 和操作系统相关的一些功能
    os.listdir("d:/") 帮我们打开一个文件夹. 返回文件夹内的所有内容(文件的名字)
    os.path.join("马化腾","马云")   马化腾/马云
    os.path.isdir(路径) 判断这个路径是文件夹还是文件

    六、二分法(三种算法)

    必须是有序的序列,才能使用二分法

    每次能排除一半的数据,效率非常高,局限很大就在要有序的序列

    fe: 普通的算法查找一个数

    lst = [4, 56, 178, 253, 625, 1475, 2580, 3574, 15963] # 时间复杂度. n
    # 让用户输入一个数n. 判断这个n是否出现在lst中
    n = int(input("请输入一个数字n:")) # 56
    for  el in lst:
        if n == el:
            print('出现了')
            break
    else:
        print("没出现")

    fe1: 非递归的二分法,须掌握,面试通常问这个

    lst = [4, 56, 178, 253, 625, 1475, 2580, 3574, 15963]
    
    n = int(input("请输入一个数:"))
    
    left = 0  # 左边界
    right = len(lst) - 1  # 右边界
    
    while left <= right:  # 当左边边界大于右边界的时候,说明不在列表中
        mid = (left + right) // 2  # 中间位置的索引
        if n > lst[mid]:  # n大于中间的数,说明要往mid右边查找
            left = mid + 1  # 新的左边界等于mid 向右移一位
        elif n < lst[mid]:
            right = mid - 1  # 新的右边界等于mid向左移一位
        else:
            print("存在")
            break
    else:
        print("不存在")

    fe2: 递归二分法,方法一:通过改变左右边界查找

    lst = [4, 56, 178, 253, 625, 1475, 2580, 3574, 15963]
    
    def binary_search(lst, n, left, right):  # 改变的左右边界
        if left > right:
            return False
        mid = (left + right) // 2  # 每次用中间的那个值去判断
        if n > lst[mid]:
            left = mid + 1
            # 当递归有返回值的时候. 需要写return. 否则有可能接收不到返回值
            return binary_search(lst, n, left, right)     # 此处必须加return, 接收返回值
        elif n < lst[mid]:
            right = mid - 1
            return binary_search(lst, n, left, right)  # 此处必须加return, 接收返回值
        else:
            print("找到了")
            return True
    
    
    n = int(input("请输入一个数字n:")) # 178
    ret = binary_search(lst, n, 0, len(lst)-1)
    print(ret)

    fe3: 二分法,方法二,通过切割列表查找

    lst = [4, 56, 178, 253, 625, 1475, 2580, 3574, 15963]
    # 切换列表
    def binary_search(lst, n):
        if len(lst) == 0:
            return False
        left = 0
        right = len(lst) - 1
        mid = (left + right) // 2
        if n > lst[mid]:
            # 当递归有返回值的时候. 需要写return. 否则有可能接收不到返回值
            return binary_search(lst[mid+1:], n)  # 每判断一次对列表进行切片
        elif n < lst[mid]:
            return binary_search(lst[:mid], n)  # 每判断一次对列表进行切片
        else:
            print("找到了")
            return True
    
    n = int(input("请输入一个数字n:")) # 178
    ret = binary_search(lst, n)
    print(ret)

    本节主要内容

    1.lambda函数  匿名函数
    2.sorted()  排序函数
    3.filter()  筛选函数
    4.map() 映射函数
    5.递归函数 (自己调用自己)
    6.二分法  (掐头去尾取中间)

    一、lambda 匿名函数

    • 只适用于一些简单的需求的设计,一句话函数

    1、语法:

    函数名 = lambda 参数: 返回值

    注意:

    1.函数的参数可以有多个,多个参数用逗号隔开
    2.匿名函数不管多复杂,只能写一行,且逻辑结束后直接返回数据
    3.返回值和正常函数一样,可以是任何数据
    4.匿名函数不是没有名字,指的是匿名的意思是通过__name__查看时是没有名字的,统一叫lambda

    fe:写法和多个参数的示例

    a = lambda n: n**n # 匿名函数, 一般不会用来做复杂的操作
    r = a(3)
    print(r)
    
    print(a.__name__) # <lambda> 匿名函数有名字. 统一叫lambda
    
    # 写一个lambda 给函数传递两个参数, a, b 计算a+b的结果
    a = lambda m, n: m + n
    
    # 写一个lambda 计算字符串长度并返回 # len()
    a = lambda s: len(s)

    二、sorted() 排序函数

    语法:

    sorted(Iterable, key = None, reverse = False)
    Iterable: 可迭代对象
    key: 排序规则(函数),sorted内部会将可迭代对象的每一个元素传递个这个函数作为参数,根据函数的运算结果进行排序
    reverse: 是否倒叙, True: 倒叙; False: 正序

    fe:根据key里面的函数进行排序

    lst = ["易", "贾克斯", "赵信", "德玛西亚", "皇子", "刀妹"]
    # 按照文字的长短来排序
    def func(s):
        return len(s)
    
    s = sorted(lst, key=func) # 把列表中的每一个元素传递给func. 根据func返回值进行排序
    print(s)

    fe2: 根据字典里面的年龄,进行排序

    lst=[{'id':3,'name':'taihei','age':18},
         {'id':1,'name':'alex','age':28},
    {'id':2,'name':'taibai','age':58},
    
    {'id':4,'name':'henhei','age':38}]
    
    # 根据年龄排序
    def func(s):
        return s['age']
    
    print(sorted(lst, key=lambda dic:dic["age"])) # 根据年龄排序

    三、filter() 筛选函数

    语法:

    filter(function, Iterable)
    function: 用来筛选的函数。 在filter中会自动的把Iterable中的元素传递给function,然后根据function
    返回的True;则保存,否者,则去掉。
    Iterable: 可迭代对象

    fe: 根据function返回的True或False,来保存数据

    lst = ["渴望", "年轮", "家有儿女", "蜗居", "49天", "浪漫满屋"]
    
    #  把后面的可迭代对象中的每一个元素交给前面的函数。 根据函数返回的True或者False。 判断是否保留该元素
    f = filter(lambda s: len(s) > 2, lst)
    print("__iter__" in dir(f))
    for el in f:
        print(el)
    
    
    lst=[{'id':3,'name':'taihei','age':18},
         {'id':1,'name':'alex','age':28},
         {'id':2,'name':'taibai','age':58},
         {'id':4,'name':'henhei','age':38}]
    
    # 筛选年龄大于等于38的人
    print(list(filter(lambda ren: ren['age']>=38, lst)))

    四、map() 映射函数

    语法:

    map(function, Iterable)
    对可迭代对象中的每一个元素进行映射,分别执行function操作,返回新的迭代对象,需要变量接收它(新的)

    fe: 对旧的可迭代对象,执行function后,全部接收,返回新的

    lst = [2, 3, 4 ,5, 6, 7, 1]
    # 计算列表中的每一项的平方
    
    # 映射
    # 把可迭代对象中的每一个元素拿出来交给前面的函数执行. 保留最后的执行结果
    m = map(lambda x: x*x, lst)
    for el in m:
        print(el)
    
    # 给出一个列表
    lst = ["alex_123", "alex_456", "wusir_123", "wusir_456", "alex_789"]
    #
    # 正确的用户名: alex
    # 密码:456
    # alex_456
    # 第一种方法
    print(list(map(lambda s : " yes" if s=="alex_456" else "false"  , lst)))
    
    # 第二种方法
    print(list(map(lambda s: s.split("_")[0] == 'alex' and s.split("_")[1] == "456",lst)))

    五、递归(函数自己调用自己,缺点占内存)

    • 在函数中调用函数本身,就是递归

    • python中最大的递归深度为1000,但实际操作中不会让你到达1000,

    • 每递归一次就要开辟一片新的一模一样的内存空间,非常占内存,增加了空间复杂度,不能用于复杂的算法

    • 由第三点可以得出,当递归有返回值时,需要写return,传递最终返回值. 否则有可能接收不到返回值(因为函数的返回值是返回给调用者)

    fe:遍历文件夹的所有文件,及打印所有文件名(非文件夹的名字)

    import os
    
    def func(path, ceng):  # path传绝对路径,层用缩进来体现文件夹的所属关系(父子级),
        lst = os.listdir(path)  # os.listdir(路径) 打开文件夹获取所有的所有内容(所有的文件名含文件夹名字)
        for el in lst:  # 当前文件夹的所有文件名(包括文件夹名字)
            # 拼接真实路径
            file_real_path = os.path.join(path, el) # os.path.join(路径, 文件名) 拼接路径和文件名, 使得可以使用这个文件名
    
            if os.path.isdir(file_real_path):  # os.path.isdir(拼接好的路径和文件名的变量) 判断是文件夹还是文件
                # 递归的入口
                print("	" * ceng, el)
                func(file_real_path, ceng + 1) # 重复刚才的操作
    
    
            else:  # 不是文件夹,是文件
                #递归的出口
                print("	" * ceng, el)
    
    func(r"E:a", 0)

    5.1 操作系统(os)相关的一些操作

    os : 和操作系统相关的一些功能
    os.listdir("d:/") 帮我们打开一个文件夹. 返回文件夹内的所有内容(文件的名字)
    os.path.join("马化腾","马云")   马化腾/马云
    os.path.isdir(路径) 判断这个路径是文件夹还是文件

    六、二分法(三种算法)

    必须是有序的序列,才能使用二分法

    每次能排除一半的数据,效率非常高,局限很大就在要有序的序列

    fe: 普通的算法查找一个数

    lst = [4, 56, 178, 253, 625, 1475, 2580, 3574, 15963] # 时间复杂度. n
    # 让用户输入一个数n. 判断这个n是否出现在lst中
    n = int(input("请输入一个数字n:")) # 56
    for  el in lst:
        if n == el:
            print('出现了')
            break
    else:
        print("没出现")

    fe1: 非递归的二分法,须掌握,面试通常问这个

    lst = [4, 56, 178, 253, 625, 1475, 2580, 3574, 15963]
    
    n = int(input("请输入一个数:"))
    
    left = 0  # 左边界
    right = len(lst) - 1  # 右边界
    
    while left <= right:  # 当左边边界大于右边界的时候,说明不在列表中
        mid = (left + right) // 2  # 中间位置的索引
        if n > lst[mid]:  # n大于中间的数,说明要往mid右边查找
            left = mid + 1  # 新的左边界等于mid 向右移一位
        elif n < lst[mid]:
            right = mid - 1  # 新的右边界等于mid向左移一位
        else:
            print("存在")
            break
    else:
        print("不存在")

    fe2: 递归二分法,方法一:通过改变左右边界查找

    lst = [4, 56, 178, 253, 625, 1475, 2580, 3574, 15963]
    
    def binary_search(lst, n, left, right):  # 改变的左右边界
        if left > right:
            return False
        mid = (left + right) // 2  # 每次用中间的那个值去判断
        if n > lst[mid]:
            left = mid + 1
            # 当递归有返回值的时候. 需要写return. 否则有可能接收不到返回值
            return binary_search(lst, n, left, right)     # 此处必须加return, 接收返回值
        elif n < lst[mid]:
            right = mid - 1
            return binary_search(lst, n, left, right)  # 此处必须加return, 接收返回值
        else:
            print("找到了")
            return True
    
    
    n = int(input("请输入一个数字n:")) # 178
    ret = binary_search(lst, n, 0, len(lst)-1)
    print(ret)

    fe3: 二分法,方法二,通过切割列表查找

    lst = [4, 56, 178, 253, 625, 1475, 2580, 3574, 15963]
    # 切换列表
    def binary_search(lst, n):
        if len(lst) == 0:
            return False
        left = 0
        right = len(lst) - 1
        mid = (left + right) // 2
        if n > lst[mid]:
            # 当递归有返回值的时候. 需要写return. 否则有可能接收不到返回值
            return binary_search(lst[mid+1:], n)  # 每判断一次对列表进行切片
        elif n < lst[mid]:
            return binary_search(lst[:mid], n)  # 每判断一次对列表进行切片
        else:
            print("找到了")
            return True
    
    n = int(input("请输入一个数字n:")) # 178
    ret = binary_search(lst, n)
    print(ret)
  • 相关阅读:
    linux下遍历目录
    C++忽略字符大小写比较
    apue.h文件找不到的解决办法
    使用Django框架
    输出程序运行的时间(精确到微秒)
    好玩的代码(1)
    在日志文件中输出当前时间
    windows下安装storm1.1.0并启动
    eclipse配置hadoop2.7.2开发环境并本地跑起来
    windows下安装并启动hadoop2.7.2
  • 原文地址:https://www.cnblogs.com/yipianshuying/p/9911229.html
Copyright © 2020-2023  润新知