python:15 递归函数和匿名函数

递归函数和匿名函数

1 递归

1.1 递归的应用场景

递归是一种编程思想,应用场景:

  1. 在我们日常开发中,如果要遍历一个文件夹下面所有的文件,通常会使用递归来实现;

  2. 在后续的算法课程中,很多算法都离不开递归,例如: 快速排序。

1.1.1 递归的特点

  • 函数内部自己调用自己
  • 必须有出口

1.2 应用:3 以内数字累加和

def sum_num(num):
    if num == 1:
        return 1

    # 由于 3 到 1 需要减两次,那么就需要递归执行两次 sum_num(num - 1)
    # 第一次递归 num = 3 - 1 = 2 ,此时 return = 3 + 2 = 5
    # 第二次递归 num = 2 - 1 , if 条件触发 return = 5 + 1 = 6 
    return num + sum_num(num - 1)

totol = sum_num(3)
print(totol)
[10:25:45 root@dev py-demo]#/bin/python3 /root/py-demo/day-1/test.py
6

1.2.1 递归函数执行流程:

  1. 当执行 sum_numbers(3) 后程序就开始调用 sum_numbers(num) 函数,通过 if 判断程序并没触发 num==1,那么就直接执行 return num + sum_numbers(num-1) 在次执行第二次的 sum_numbers(num)
  2. sum_numbers(num -1) 此时 num = 3 - 1 = 2 if 判断程序并没触发 ,那么就直接执行 return num + sum_numbers(num-1)
  3. sum_numbers(num -1) 此时 num = 2 - 1 = 1 if 判断触发,return 1 给步骤 2 ,此时在步骤 2 中 num = 2 + 1 = 3 ,紧接着步骤 2 将 return num + sum_numbers(num-1) = 3 + 3 = 6 结果 return 给步骤 1
  4. 此时 sum_numbers(3) = 6

    以上就是程序递归函数的整个流程

1.2.2 递归出口

递归我们都知道有两个特点:

  1. 函数内部自己调用自己
  2. 递归必须要有出口

假如我们在递归函数没有添加递归出口那会出现什么问题呢?

def sum_num(num):
    # 递归程序出口
    # if num == 1:
    #     return 1

    return num + sum_num(num - 1)

totol = sum_num(3)
print(totol) 

在上面代码中我将 if 递归函数程序出口注释掉,程序就会立马报错

[10:25:45 root@dev py-demo]#/bin/python3 /root/py-demo/day-1/test.py
Traceback (most recent call last):
  File "/root/py-demo/day-1/test.py", line 8, in <module>
    totol = sum_num(3)
  File "/root/py-demo/day-1/test.py", line 6, in sum_num
    return num + sum_num(num - 1)
  File "/root/py-demo/day-1/test.py", line 6, in sum_num
    return num + sum_num(num - 1)
  File "/root/py-demo/day-1/test.py", line 6, in sum_num
    return num + sum_num(num - 1)
  [Previous line repeated 996 more times]
RecursionError: maximum recursion depth exceeded

# 直接报错,报错位置都是分别带有函数递归的位置
# maximum recursion depth exceeded:超出最大递归深度,这里为 996

所谓的递归深度,就是函数自己调用自己的次数,并不会像死循环一直调用,所以在工作中写递归函数的时候需要提前写好递归出口

2 lambda 表达式

lambda 在 python 中用于定义匿名函数,从而实现

2.1 lambda 的应用场景

如果一个函数有一个返回值,并且只有一句代码,可以使用 lambda 简化

但是我们都知道当我们开辟函数的时候都需要有一块内存用来存储,所以 lambda 也是如此也需要有一个块内存空间用来做存储,但是在普通函数执行是占用的内存空间要大于 lambda 执行时的内存空间

也就是说如果使用 lambda 就会让服务器的负载以及资源减轻,也能减少程序员的代码量

2.2 lambda 语法

lambda 参数列表: 表达式

注意:

  • lambda 表达式的参数可有可无,函数的参数在 lambda 表达式中完全适用。
  • lambda 表达式能接收任何数量的参数但只能返回一个表达式的值。

2.2.1 快速入门

# 传统函数
def fn1():
    return 200

# 输出 function
print(fn1)
# 输出 200
print(fn1())

# 通过 lambda 定义 fn2 匿名函数,并且返回值为 100
fn2 = lambda: 100
# 输出 <function <lambda> 说明 fn2 是匿名函数类型, <lambda>
print(fn2)
# 输出 100
print(fn2())
[14:16:00 root@dev py-demo]#/bin/python3 /root/py-demo/day-1/test.py
<function fn1 at 0x7f2cc038f310>
200
<function <lambda> at 0x7f2cc020fd30>
100

注意:

直接打印 lambda 表达式,输出的是此 lambda 的内存地址

2.3 示例:计算 a + b

2.3.1 函数实现

# 通过传统函数实现
def add(a,b):
    return a+b

print(add(1,2))

注意:

可以看到我们通过两行代码实现了 add 函数的功能

2.3.2 lambda 实现

# add = lambda 定义 add 匿名函数
# a , b 定义匿名函数 add 的形参
# : a + b 返回 a + b
add = lambda a , b : a + b
print(add(1,2))
[14:24:22 root@dev py-demo]#/bin/python3 /root/py-demo/day-1/test.py
3

2.4 lambda 的参数形式

2.4.1 无参数

fn1 = lambda: 100
print(fn1())
[15:29:43 root@dev py-demo]#/bin/python3 /root/py-demo/day-1/test.py
100

2.4.2 一个参数

如果当 lambda 有参数,那么在函数调用的时候一定要传入数据

# 定义匿名函数 lambda, 接收形参 a 返回值为 a
fn1 = lambda a : a
print(fn1('hello world!'))
[09:18:56 root@dev py-demo]#/bin/python3 /root/py-demo/day-1/test.py
hello world!

2.4.3 默认参数

默认参数还有另外一个名字叫做缺省参数,所谓的默认参数指的就是带有默认值的参数,这种参数的特点就是当函数调用的时候,可为默认参数传值也可以不传值,如果为默认参数传值那么就覆盖原有默认参数,而是用新数据,如果不传值我们的程序也不会报错

# 这里通过 lambda 定义形参,而且给 c 定义默认值为 100
fn1 = lambda a , b , c = 100: a + b + c
print(fn1(10,20))
[09:44:39 root@dev py-demo]#/bin/python3 /root/py-demo/day-1/test.py
130

2.4.4 可变参数 *args

*args 用来接收我们不定长的位置使用,返回的值为元组

fn1 = lambda *args : args
print(fn1(10,20,30))
[09:44:50 root@dev py-demo]#/bin/python3 /root/py-demo/day-1/test.py
(10, 20, 30)

2.4.5 可变参数 **kwargs

接收不定长关键字参数,返回字典

# 接收 name = tome ,age = 10
fn1 = lambda **kwargs : kwargs
print(fn1(name="tome",age=10))
[09:53:28 root@dev py-demo]#/bin/python3 /root/py-demo/day-1/test.py
{'name': 'tome', 'age': 10}

2.5 lambda 应用

2.5.1 带判断的 lambda

通过 if 进行判断

# a if a > b else b 三目运算,if 判断 a > b 为真就返回 a ,否则返回 b 
# 因为条件成立的返回值是最前面的那个参数
# else 后面就是跟的条件不成立返回值
fn1 = lambda a , b : a if a > b else b
print(fn1(10,20))
# 返回 20 传入给 b 值比 a 值大
[09:53:39 root@dev py-demo]#/bin/python3 /root/py-demo/day-1/test.py
20

2.5.2 列表数据按字典 key 的值排序

需要实现将列表里面的字典数据进行排序,排序的基准是按照字典的某个 key 值进行升序或降序排序,在工作中一般用于用户的个人信息进行存储,通过 name 字段进行排序,也可以通过 age 等其他字段进行排序

students = [
    {'name':'tom','age' : 18},
    {'name':'ayn','age' : 17},
    {'name':'ste','age' : 19},
    {'name':'mot','age' : 20},
]

# 通过 students.sort 内置函数进行排序,这里通过 key 为 name 进行排序
# key 为一个 lambda 匿名函数的表达式
# lambda x ,这里的 x 是表示用来升序或者降序的排序,而在这里就是一个字典
students.sort(key=lambda x : x['name'])
print(students)

# 年龄升序排序
students.sort(key= lambda x : x['age'])
print(students)

# 降序通过 reverse = True 实现降序排序反转,如果不屑 reverse 默认为升序
students.sort(key= lambda x : x['name'],reverse= True)
print("name 降序:\n",students)

students.sort(key= lambda x : x['age'],reverse= True)
print("age 降序:\n",students)
[10:48:29 root@dev py-demo]#/bin/python3 /root/py-demo/day-1/test.py
[{'name': 'ayn', 'age': 17}, {'name': 'mot', 'age': 20}, {'name': 'ste', 'age': 19}, {'name': 'tom', 'age': 18}]
[{'name': 'ayn', 'age': 17}, {'name': 'tom', 'age': 18}, {'name': 'ste', 'age': 19}, {'name': 'mot', 'age': 20}]
name 降序:
 [{'name': 'tom', 'age': 18}, {'name': 'ste', 'age': 19}, {'name': 'mot', 'age': 20}, {'name': 'ayn', 'age': 17}]
age 降序:
 [{'name': 'mot', 'age': 20}, {'name': 'ste', 'age': 19}, {'name': 'tom', 'age': 18}, {'name': 'ayn', 'age': 17}]
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇