python---第13天---高阶函数

python—第13天—高阶函数

函数参数

在设计函数的时候,函数的参数个数是暂时无法确定的

arguments —> args —> 参数

位置参数 —> position arguments
关键字参数 —> keyword arguments

*args —> 可变参数 —> 可以接收零个或任意多个位置参数 —> 将所有的位置参数打包成一个元组
**kwargs —> 可以接受零个或任意多个关键字参数 —> 将所有关键字参数打包成一个字典

def add(*args, **kwargs):
	"""相加"""

    total = 0
    for arg in args:
        if type(arg) in (int, float):
            total += arg
    for value in kwargs.values():
        if type(value) in (int, float):
            total += value
    return total


def mul(*args, **kwargs):
	"""相乘"""

    total = 1
    for arg in args:
        if type(arg) in (int, float):
            total *= arg
    for value in kwargs.values():
        if type(value) in (int, float):
            total *= value
    return total
    
    
print(add(1, 2, 3, 4))
print(mul(1, 2, 3, 4))

高阶函数

Python中的函数是一等函数(一等公民)

  1. 函数可以作为函数的参数
  2. 函数可以作为函数的返回值
  3. 函数可以赋值给变量

如果把函数作为函数的参数或者返回值,这种玩法通常称之为高阶函数

通常使用高阶函数可以实现对原有函数的解耦合操作。

# fn ---> 一个实现二元运算的函数(可以做任意的二元运算)
def calc(*args, op, init_value=0, **kwargs):
    total = init_value
    for arg in args:
        if type(arg) in (int, float):
            total = op(total, arg)
    for value in kwargs.values():
        if type(value) in (int, float):
            total = op(total, value)
    return total


# 加法运算
print(calc(11, 22, 33, 44, op=lambda x, y: x + y))
# 乘法运算
print(calc(11, 22, 33, 44, init_value=1, op=lambda x, y: x * y))
# 减法运算
print(calc(11, 22, 33, 44, init_value=100, op=lambda x, y: x - y))

运算 - operator - op

Lambda函数 — 没有名字而且一句话就能写完

这里我们也可以使用operator函数,里面就有各类运算

练习1:

编写实现对列表元素进行冒泡排序的函数

def bubble_sort(items, asending=True, gt=lambda x, y: x > y):
    """冒泡排序

    :param items: 待排序列表
    :param asending: 是否升序
    :param gt: 比较两个元素大小的函数
    :return: 排序后的列表
    """
    # 保证原有列表不改变
    items = items[:]
    for i in range(1, len(items)):
        swapped = False
        for j in range(i, len(items) - i):
            if gt(items[j], items[j + 1]):
                items[j], items[j + 1] = items[j + 1], items[j]
                swapped = True
        if not swapped:
            break
    # 控制排序是升序还是降序,默认升序
    if not asending:
        items = items[::-1]
    return items


if __name__ == '__main__':
    nums = [2, 6, 5, 1, 3, 4]
    print(bubble_sort(nums, ))
    print(bubble_sort(nums, False))
    # 使用lambda函数,实现对字符串长度进行比较
    words = ['apple', 'watermelon', 'zoo', 'banana']
    print(bubble_sort(words, gt=lambda x, y: len(x) > len(y)))

练习2:

编写实现查找列表元素的函数

列表元素无序 —> 顺序查找

列表元素有序 —> 二分查找(折半查找)

def seq_search(items, key):
	"""顺序查找"""
    for index, item in enumerate(items):
        if item == key:
            return index
    return -1


def bin_search(items, key, *, cmp=lambda x, y: x - y):
	"""二分查找"""
    start, end = 0, len(items) - 1
    while start <= end:
        mid = (start + end) // 2
        if cmp(key, items[mid]) > 0:
            start = mid + 1
        elif cmp(key, items[mid]) < 0:
            end = mid + 1
        else:
            return mid
    return -1
    
if __name__ == '__main__':
    nums = [1, 2, 3, 4, 5, 6, 7, 8, 9]
    print(bin_search(nums, 8))
    print(seq_search(nums, 2))

函数可以自己调用自己吗???

函数如果直接或间接的调用自身,这种调用为递归调用

不管函数是调用别的函数,还是调用自身,一定要做到快速收敛

再比较有限的调用次数内能够结束,而不是无限制的调用函数。

如果一个函数(通常之递归调用的函数)不能够快速收敛,那么就很有可能产生下面错误

RecursionError: maximum recursion depth exceeded 最终导致程序的崩溃

递归函数的两个要点:

1.递归公式(第n次跟第n-1次的关系)

2.收敛条件(什么时候停止递归调用)

def fac(num):
    """求阶乘(递归调用写法)"""
    if num == 0:
        return 1
    return num * fac(num - 1)


if __name__ == '__main__':
    print(fac(5))

练习:斐波拉契数

1, 1, 2, 3, 5, 8, 13, 21
f(n) = f(n - 1) + f(n - 2)

def fib(n):
    if n in (1, 2):
        return 1
    return fib(n - 1) + fib(n - 2)

从第35个斐波拉契数开始,速度就变慢了,我们可以创建一个字典来储存前面的值,这样就能大大提高效率

优化后:

def fib(n, temp={}):
    if n in (1, 2):
        return 1
    if n not in temp:
        temp[n] = fib(n - 1) + fib(n - 2)
    return temp[n]
    
    
if __name__ == '__main__':
	for i in range(1, 121):
        print(i, fib(i))

练习:汉诺塔(梵塔)问题的求解

算法:假设有 A、B、C三个塔,A 塔有 N 块盘, 目标是把这些盘全部移到 C 塔。那么先把 A 塔顶部的 N - 1 块盘移动到 B 塔, 再把 A 塔剩下的大盘移到 C, 最后把 B 塔的 N - 1 块盘移到 C。

def toh(n, a, b, c):
    if n == 1:
        print(a, '--->', c)
    else:
        toh(n - 1, a, c, b)
        toh(1, a, b, c)
        toh(n - 1, b, a, c)


if __name__ == '__main__':
    toh(3, 'A', 'B', 'C')
  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值