学习Python第三周的第三天
一、参数
-
位置参数——在没有特殊处理的情况下,函数的参数都是位置参数
-
关键字参数——我们在设计函数时,如果既不知道调用者会传入的参数个数,也不知道调用者会不会指定参数名,那么同时使用可变参数和关键字参数。关键字参数会将传入的带参数名的参数组装成一个字典,参数名就是字典中键值对的键,而参数值就是字典中键值对的值
重点提醒:关键字参数一定要在位置参数的后面。
代码例子如下:
# *args--->可变参数--->可以接收零个或任意多个位置参数--->将位置参数打包成元组
# **kwargs--->可以接收零个或任意多个关键字参数--->将所有的关键字参数打包成一个字典
def add(*args, **kwargs):
print(args, type(args))
# print(kwargs, type(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
print(add(1, 2, 4, a=3))
def mul(*args, **kwargs):
# print(args, type(args))
# print(kwargs, type(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(mul(1, 2, 4, a=3))
二、高阶函数
Python中的函数是一等函数,但是函数本身也可以作为函数的参数或返回值,而且还可以赋值给变量。这就是所谓的高阶函数。通常使用高阶函数可以实现对原有函数的解藕合操作。
Lambda函数——没有名字而且一句话就能写完的函数,唯一的表达式就是函数的返回值。也被称为匿名函数
例如:
# 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))
三、递归调用
函数如果直接或者间接的调用了自身,那么这种调用就被称为递归调用。
递归函数的两个要点:
- 递归公式(第n次跟第n-1次的关系)
- 收敛条件(什么时候停止递归调用)
# 不管函数是调用别的函数,还是调用自身,一定要做到快速收敛。
# 在比较有限的调用次数内能够结束,而不是无限制的调用函数。
# 如果一个函数(通常指递归调用的函数)不能够快速收敛,那么就很有可能产生下面的错误
# RecursionError: maximum recursion depth exceeded
# 最终导致程序的崩溃。
def fac(num: int) -> int:
"""求阶乘(递归写法)"""
if num == 0:
return 1
return num * fac(num - 1)
if __name__ == '__main__':
# return 5 * fac(4)
# return 4 * fac(3)
# return 3 * fac(2)
# return 2 * fac(1)
# return 1 * fac(0)
# return 1
print(fac(5))
def fib(n):
if n in (1, 2):
return 1
return fib(n - 1) + fib(n - 2)
if __name__ == '__main__':
for i in range(1, 21):
print(i, fib(i))
例题一:编写实现对列表元素进行冒泡排序的函数
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, 7, 20, 8, 15]
print(bubble_sort(nums, ascending=False))
print(nums)
例题二:编写实现查找列表元素的函数:
def seq_search(items: list, key) -> int:
"""
顺序查找
:param items: 待查找的元素
:param key: 要找的元素
:return: 找到了返回元素的索引,找不到返回-1
"""
for index, item in enumerate(items):
if item == key:
return index
return -1
def bin_search(items: list, key) -> int:
"""
二分查找
:param items:待查找的元素(元素有序)
:param key: 要找的元素
:return: 找到了返回元素的索引,找不到返回-1
"""
start, end = 0, len(items) - 1
while start <= end:
mid = (start + end) // 2
if key > items[mid]:
start = mid + 1
elif key < items[mid]:
end = mid - 1
else:
return mid
return -1
if __name__ == '__main__':
nums1 = [5, 4, 7, 20, 8, 15]
print(seq_search(nums1, 20))
print('_' * 20)
nums2 = [4, 5, 7, 8, 15, 20]
print(bin_search(nums2, 15))
print(bin_search(nums2, 45))
四、简单的总结
Python中的函数可以使用可变参数*args
和关键字参数**kwargs
来接收任意数量的参数,而且传入参数时可以带上参数名也可以没有参数名,可变参数会被处理成一个元组,而关键字参数会被处理成一个字典。Python中的函数也是对象,所以函数可以作为函数的参数和返回值,也就是说,在Python中我们可以使用高阶函数。如果我们要定义的函数非常简单,只有一行代码且不需要名字,可以将函数写成Lambda函数(匿名函数)的形式。