day15

1. lambda匿名函数

# lambda表⽰的是匿名函数. 不需要⽤def来声明, ⼀句话就可以声明出⼀个函数
# 语法: 函数名 = lambda 参数: 返回值

# 普通的正常的函数
    def func(n):
        return n * n

    ret = func(9)
    print(ret)

# 匿名函数
    a = lambda n: n * n
    ret = a(9)
    print(ret)

    print(a(5))      # 函数的名字可以认为是a

# 匿名函数并不是说⼀定没有名字. 这⾥前⾯的变量就是⼀个函数名. 说他是匿名原因# 是我们通过__name__查看的时候是没有名字的. 统⼀都叫lambda. 在调⽤的时候没有什么特别之处.像正常的函数调⽤即可
    print(func.__name__)  # 查看函数的名字, (函数的名字可能被赋值过,你看到的不一定是它的名字)
    print(a.__name__)  # __name__的值都是<lambda>

# 返回值是元祖
    def func(x, y):
        return x, y  # 返回的是元组
    print(func(1, 2))  # (1,, 2)

    c = 1, 2  # 1,2 是元组
    print(c)  # (1, 2)


# lambda返回多个值的坑
    suiyi = lambda x, y: x, 123  # 这是lambda x, y: x是一个整体,它和后面的123整体是一个元组
    print(suiyi)  # (<function <lambda> at 0x0000013CA75E9510>, 123)

# 多个返回值需要括起来成为一个元素(lamda返回值是一个元素),最后返回一个元组(一个元素)
    suiyi = lambda x, y: (x, y)
    print(suiyi(1, 2))  # (1, 2)

# 注意:
    # 1. 函数的参数可以有多个. 多个参数之间⽤逗号隔开
    # 2. 匿名函数不管多复杂. 只能写⼀⾏, 且逻辑结束后直接返回数据(太复杂就不要用lamda函数写了)
    # 3. 返回值和正常的函数⼀样, 可以是任意数据类型

# 笔试题
    suiyi = lambda x, y: 1, 2  # 换成数值不显示报错,但是运行不出来
    print(suiyi)  # (<function <lambda> at 0x00000270F54DC1E0>, 2)
    print(suiyi(250, 38))  # TypeError: 'tuple' object is not callable

# 练习: 匿名函数, 给函数传递2个参数, 返回最大值
    # 用三元运算符(只用于2个数的比较)
    a = lambda x, y: x if x > y else y
    print(a(6, 9))

    # 用max(), (用于多个数的比较)
    b = lambda x, y: max(x, y)
    print(b(1, 2))

# 难度升级, 传递多个参数, 返回最大值
    fn = lambda *args: max(args)  # 单行函数
    print(fn(6, 1, 3, 4, 2, 8, 99))

2. sorted()

# sorted 排序函数
# 语法: sorted(Iterable, key=None, reverse=False)
# (1) Iterable: 可迭代对象
# (2) key: 排序方案, sorted函数内部会把可迭代对象中的每一个元素交给后面的key
# 后面的key计算出一个数字. 作为当前这个元素的权重, 整个函数根据权重进行排序
# (3) reverse: 是否是倒叙.  False: 正序, True: 倒叙. (不写就默认是 True: 正序)

# 长度      2       3         4         3        3       2      2
lst = ["聊斋", "西游记", "三国演义", "葫芦娃", "水浒传", "年轮", "亮剑"]


def func(s):
    return len(s)  # 按照元素的长度大小来排序
    # return len(s) % 2  # 按照元素长度除以2的余数大小来排序


ll = sorted(lst, key=func)  # func("聊斋", "西游记", ...)

print(ll)
# 结果: ['聊斋', '年轮', '亮剑', '西游记', '葫芦娃', '水浒传', '三国演义']

3. filter()

#  filter  筛选函数
#  语法: filter(function, Iterable)
#  function: ⽤来筛选的函数. 在filter中会⾃动的把iterable中的元素传递给function. # 然后根据function返回的True或者False来判断是否保留此项数据

    lst = [
        {"name": "汪峰", "score": 48},
        {"name": "章子怡", "score": 39},
        {"name": "闫康琪", "score": 97},
        {"name": "理想", "score": 90}
    ]

    f = filter(lambda el: el['score'] > 60, lst)  # 留下的人

    print(list(f))
# 结果: [{'name': '闫康琪', 'score': 97}, {'name': '理想', 'score': 90}]

4. map()

# map  映射函数
# 语法: map(function, iterable) 可以对可迭代对象中的每⼀个元素进⾏映射. 分别取执⾏function

    m = map(lamda el: el**2, lst)  # 把后面的可迭代对象中的每一个元素传递给function, 结果就function的返回值

    print(list(m))  # 拿出所有值到一个列表里

# 分而治之, 一层一层处理(思想很重要)
# map(func1, map(func2, map(func3, lst)))

# 计算两个(不只两个)列表中相同位置的数据的和
    lst1 = [1, 3, 5, 7]
    lst2 = [2, 4, 6, 8, 10]
    # 水桶效应, zip()
    m = map(lambda x, y, z: x + y + z, lst1, lst2, [5, 1, 2, 3, 6])
    print(list(m))
# 结果: [8, 8, 13, 18]

5. 递归函数

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

count = 1
def func():
    global count
    print("alex是很帅的", count)

    count = count + 1
    func()
func()

# 题1
# 遍历D:/TIM文件夹, 打印出所有的文件和普通文件的文件名 # 输出格式 # d:/TIM # 05.pdf # 06.pdf # s15: # day01: # 01xxx # 02xxx import os def func(filepath, n): # 1. 打开这个文件夹 files = os.listdir(filepath) # 2. 拿到每一个文件名 for file in files: # 文件名 # 3. 获取到路径.(文件名没办法直接判断,需要加上路径) f_d = os.path.join(filepath, file) # d:/TIM/文件名 # 4. 判断是否是文件夹 if os.path.isdir(f_d): # 5. 如果是文件夹. 继续再来一遍 print(" "*n, file,":") # 打印文件名 func(f_d, n+1) else: # 不是文件夹. 普通文件 print(" "*n, file) func("d:/TIM", 0)

6. 二分查找

# 使用二分法可以提高效率, 前提条件: 有序序列
# 二分法核心思想: 掐头掐尾取中间, 一次砍一半.

# 2**n < 数据量  # n 比较次数
# 100000000  有一亿个数,判断一个数在不在里面, 比较27次就可以
# print(2**27)  # 二分法27次可以比较134217728个数

# 二分查找--非递归
    lst = [22, 33, 44, 55, 66, 77, 88, 99, 101, 238, 345, 456, 567, 678, 789]
    n = 66

    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:
            mid = (left + right)//2
            if n > lst[mid]:  # 在右边
                left = mid + 1  # 把左边界变成mid,然后右移一位
                # 个人理解: 一层一层函数递归进去,但是结果也要一层一层返回回来到第一层
                return func(n, left, right)  # 递归  递归的入口
            if n < lst[mid]:  # 在左边
                right = mid - 1   # 把右边界mid,然后左移一位
                # 深坑. 函数的返回值返回给调用者
                return func(n, left, right)  # 递归
            if n == lst[mid]:
                print("找到了")
                return mid  # 通过return返回, 终止递归
                # return  # 通过return返回. 终止递归
        else:
            print("没有这个数")  # 递归的出口
            return -1  # 1, 索引+ 2, 什么都不返回, None(避免返回None)
    
    # 找66, 左边界:0, 右边界是:len(lst) - 1
    print(func(63, 0, len(lst)-1))
原文地址:https://www.cnblogs.com/kangqi452/p/11340393.html