文章目录
- Python学习的第十七天:函数的进阶
- 函数的参数
- 函数的递归
Python学习的第十七天:函数的进阶
函数的参数
- arguments —> args —> 参数
- 位置参数 —> positional argument
- 关键字参数 —> keyword argument —> 参数名=参数值
- 关键字参数一定是在位置参数的后面
- Python中的函数是一等函数,满足条件:
- 函数可以作为函数的参数
- 函数可以作为函数的返回值
- 函数可以赋值给变量
- 如果把函数作为函数的参数或者返回值,这种玩法通常称之为高阶函数。
通常使用高阶函数可以实现对原有函数的解耦合操作。 - 运算 - operate,运算符 - operator
- Lambda函数 —> 没有名字而且一句话就能写完的函数,唯一的表达式就是函数的返回值
# *args ---> 可变参数 ---> 可以接收零个或任意多个位置参数 ---> 将所有的位置参数打包成一个元组
# **kwargs ---> 可以接收零个或任意多个关键字参数 ---> 将所有的关键字参数打包成一个字典
#相加
# *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 sub(init_value, *args, **kwargs):
total = init_value
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(11, 22, 33, 44))
print(mul(11, 22, 33, 44))
fn = mul
print(fn(1, 2, 3, 4, 5))
)]
# 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
def add(x, y):
return x + y
def mul(x, y):
return x * y
print(calc(11, 22, 33, 44, op=add))
print(calc(11, 22, 33, 44, op=lambda x, y: x + y))
print(calc(11, 22, 33, 44, op=mul, init_value=1))
print(calc(11, 22, 33, 44, init_value=1, op=lambda x, y: x * y))
fn = lambda x, y: x - y
print(calc(11, 22, 33, 44, init_value=100, op=fn))
# 通过函数实现冒泡排序
def bubble_sort(items, *, ascending=True, gt=lambda x, y: x > y):
"""冒泡排序
:param items: 待排序的列表
:param ascending: 是否使用升序
:param gt: 比较两个元素大小的函数
:return: 排序后的列表
"""
# 设计函数的时候,一定要注意函数的无副作用性(调用函数不影响调用者)
# 通过索引运算复制一个相同的列表
items = items[:]
for i in range(1, len(items)):
swapped = False
for j in range(0, 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 ascending:
items = items[::-1]
return items
if __name__ == '__main__':
nums = [35, 96, 12, 78, 56, 64, 39, 80]
print(bubble_sort(nums, ascending=False))
# print(nums)
words = ['apple', 'watermelon', 'hello', 'zoo', 'internationalization']
# 按照字符串长度进行排序
print(bubble_sort(words, gt=lambda x, y: len(x) > len(y), ascending=False))
函数的递归
- 函数如果直接或间接的调用了自身,这种调用称为递归调用。
- 不管函数是调用别的函数,还是调用自身,一定要做到快速收敛。
- 在比较有限的调用次数内能够结束,而不是无限制的调用函数。
- 如果一个函数(通常指递归调用的函数)不能够快速收敛,那么就很有可能产生下面的错误
RecursionError: maximum recursion depth exceeded
最终导致程序的崩溃。 - 递归函数的两个要点:
- 递归公式(第n次跟第n-1次的关系)
- 收敛条件(什么时候停止递归调用)
# 通过函数求阶乘
# 阶乘的定义:
# ~ n! = n * (n - 1) * (n - 2) * ... * 2 * 1
# ~ n! = n * (n - 1)!
def fac(num: int) -> int:
"""求阶乘(递归写法)"""
if num == 0:
return 1
return num * fac(num - 1)
if __name__ == '__main__':
print(fac(5))