前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python基础10-函数的递归

Python基础10-函数的递归

作者头像
DriverZeng
发布2022-09-26 11:44:52
2130
发布2022-09-26 11:44:52
举报
文章被收录于专栏:Linux云计算及前后端开发

-曾老湿, 江湖人称曾老大。


-多年互联网运维工作经验,曾负责过大规模集群架构自动化运维管理工作。 -擅长Web集群架构与自动化运维,曾负责国内某大型金融公司运维工作。 -devops项目经理兼DBA。 -开发过一套自动化运维平台(功能如下): 1)整合了各个公有云API,自主创建云主机。 2)ELK自动化收集日志功能。 3)Saltstack自动化运维统一配置管理工具。 4)Git、Jenkins自动化代码上线及自动化测试平台。 5)堡垒机,连接Linux、Windows平台及日志审计。 6)SQL执行及审批流程。 7)慢查询日志分析web界面。


函数递归介绍


什么是函数递归

函数嵌套调用的一种特殊形式,在调用一个函数的过程中,又直接或间接的调用该函数本身,称之为函数的递归调用

例如:

代码语言:javascript
复制
def foo():
    print('from foo')
    foo()

foo()

函数调用深度

代码语言:javascript
复制
def foo(n):
    print('from foo',n)
    foo(n+1)

foo(0)

代码语言:javascript
复制
def bar():
    print('from bar')
    foo()
    
def foo():
    print('from foo')
    bar()

foo()

以上的这两种,都没有啥意义,调用完,报错...

代码语言:javascript
复制
递归调用必须有两个明确的阶段
1.回溯:一次次递归调用下去,但是需要注意的是,每一次重复,问题的规模都应该有所减少,直到最小值,即回溯阶段要有一个明确的结束条件.
2.递推:往回一层一层的推算出结果

def age(n):
    if n == 1:
        return 18
    return age(n-1) + 2
print(age(5))

为啥要用递归?

举个栗子:

有一个列表 l=[1,[2,[3,[4,[5,[6,[7,[8,[9,[10,[11,]]]]]]]]]]]

想取出里面的数据

代码语言:javascript
复制
l=[1,[2,[3,[4,[5,[6,[7,[8,[9,[10,[11,]]]]]]]]]]]

for item in l:
    if type(item) is not list:
        print(item)
    else:
        for i in item:
                if type(i) is not list:
                    print(i)
                else:
                    for n in i:
                        print(n)

代码还没写完,无限循环下去吧...

此时此刻,用递归函数就会好很多,递归只需要把控好结束条件,代码如下,它不香嘛?

代码语言:javascript
复制
l=[1,[2,[3,[4,[5,[6,[7,[8,[9,[10,[11,]]]]]]]]]]]
def search(l):
    for item in l:
        if type(item) is not list:
            print(item)
        else:
            search(item)

search(l)


函数递归调用应用于算法

现在有一个列表,里面有很多个数字,从小到排列,现有需求找到某一个数字 nums=[13,15,17,23,31,53,74,81,93,102,201,303,403,503,777]

代码语言:javascript
复制
# 需求一:找到15
nums=[13,15,17,23,31,53,74,81,93,102,201,303,403,503,777]
find_num=15
for num in nums:
    if num == find_num:
        print('find it:',num)
        break

## emm...运气好 ,15就在第二个,两次就找到了
## 如果找503呢?
## 如果这个数字列表有一万个字呢?
## 效率是不是很低?

# 需求二:提高效率(二分法)
def binary_search(nums,find_num):
    print(nums)
    mid_index=len(nums) // 2
    if find_num > nums[mid_index]:
        # in the right
        nums=nums[mid_index+1:]
        binary_search(nums,find_num)
    elif find_num < nums[mid_index]:
        # in the left
        nums=nums[0:mid_index]
        binary_search(nums, find_num)
    else:
        print('find it',nums[mid_index])


binary_search(nums,find_num)

用了4次就可以找到

三元表达式


作用

会:可以让自己的代码变的更简洁 不会:也没有太大影响...


举例

代码语言:javascript
复制
# 以前我们写过一个函数,比较两个数的大小
def max2(x,y):
    if x > y:
        return x
    else:
        return y

print(max2(1,10))

# 三元表达式实现
def max2(x,y):
   return x if x > y else y
print(max2(1,10))


# 再举个例子
name=input('your name: ').strip()
res="SB" if name == "haifeng" else "NB"
print(res)

列表生成式\字典生成式\集合生成式


列表生成式

代码语言:javascript
复制
# 语法
[expression for item1 in iterable1 if condition1
for item2 in iterable2 if condition2
...
for itemN in iterableN if conditionN
]
类似于
res=[]
for item1 in iterable1:
    if condition1:
        for item2 in iterable2:
            if condition2
                ...
                for itemN in iterableN:
                    if conditionN:
                        res.append(expression)

# 优点:方便,改变了编程习惯,可称之为声明式编程

举例

现有一个名字的列表 names=['qls','lls','zhang3','li4','wang5']

代码语言:javascript
复制
# 需求一:将名字后面都加上一个"大帅比"的后缀
names=['qls','lls','zhang3','li4','wang5']
l=[]
for name in names:
    res=name + '_DSB'
    l.append(res)

print(l)

## 罗里吧嗦,很麻烦
# 使用列表生成式,一行代码搞定
names=['qls','lls','zhang3','li4','wang5']
l=[name + 'DSB' for name in names]
print(l)


# 需求二:将列表中,zls这个名字排除在外
names=['qls_sb','lls_sb','zhang3_sb','li4_sb','wang5_sb','zls']
l=[]
for name in names:
    if name.endswith('sb'):
        l.append(name)
print(l)

# 列表生成式,加判断
l=[name for name in names if name.endswith('sb')]
print(l)

字典生成式

现有两个列表 keys=['name','age','gender'] values=['zls',18,'male']

代码语言:javascript
复制
# 补充技巧 ,python内置enumerate()方法
l=['a','b','c','d']
for item in enumerate(l):
    print(item)

代码语言:javascript
复制
# 那么我们变量解压
l=['a','b','c','d']
for i,v in enumerate(l):
    print(i,v)

代码语言:javascript
复制
# 需求一:把这两个列表,合并成一个字典
keys=['name','age','gender']
values=['zls',18,'male']
dic={}
for i,k in enumerate(keys):
    dic[k] = values[i]

print(dic)

# 需求二:字典生成式,一行代码搞定
keys=['name','age','gender']
values=['zls',18,'male']
dic={k:values[i] for i,k in enumerate(keys)}
print(dic)

# 需求三:字典生成式,加判断
keys=['name','age','gender']
values=['zls',18,'male']
dic={k:values[i] for i,k in enumerate(keys) if i > 0}
print(dic)

集合生成式

代码语言:javascript
复制
# 和字典生成式比较
## 字典
print({i:i for i in range(10)})

## 集合
print({i for i in range(10)})

但是,集合有两个特性: 1.去重 2.无序

代码语言:javascript
复制
# 例如
print({i for i in 'hello'})

# 结果

匿名函数


什么是匿名函数?

匿名:就是没有名字 匿名函数:没有名字的函数

以前我们在定义函数的时候,为啥有名字呢?因为我们要保存下来,需要开辟一块内存空间,那么为什么要用匿名函数呢?作用就是,为了这个函数我们只使用一次的时候,不需要占用内存,没有重复使用的需求。


举例

代码语言:javascript
复制
# 写一个求和的函数
def sum2(x,y):
    return x+y

print(sum2(1,5))

# 匿名函数
lambda x,y:x+y

# 打印出来,会发现是一个内存地址,如此一来,我们加上括号就可以调用
print(lambda x,y:x+y)

# 错误写法
print(lambda x,y:x+y(1,2))

## 打印出来,还是内存地址,为啥呢... 因为是y(1,2),所以我们需要,把整个函数括起来

# 正确写法
print((lambda x,y:x+y)(1,2))


匿名函数配合其他函数使用

内置函数:max,min,sorted,map,filter,reduce 自定义函数:xxx

代码语言:javascript
复制
# 现有一薪资列表
salaries={
    'zls':10000000,
    'qls':10000,
    'lls':11111,
    'zhang3':100,
    'li4':1
}

# 需求一:max 求出薪资最高的人名:即比较的是字典的value,但是取的结果是key
salaries={
    'zls':10000000,
    'qls':10000,
    'lls':11111,
    'zhang3':100,
    'li4':1
}

def func(name):
    return salaries[name]
res=max(salaries,key=func)
print(res)

# 使用匿名函数
salaries={
    'zls':10000000,
    'qls':10000,
    'lls':11111,
    'zhang3':100,
    'li4':1
}

res=max(salaries,key=lambda name:salaries[name])
print(res)

## 需求二:min 求最小薪资
salaries={
    'zls':10000000,
    'qls':10000,
    'lls':11111,
    'zhang3':100,
    'li4':1
}

res=min(salaries,key=lambda name:salaries[name])
print(res)

# 需求三:使用 sorted 排序,按照薪资从小到大排序(从大到小 reverse=True 即可)
salaries={
    'zls':10000000,
    'qls':10000,
    'lls':11111,
    'zhang3':100,
    'li4':1
}
res=sorted(salaries,key=lambda name:salaries[name])
print(res)

res=sorted(salaries,key=lambda name:salaries[name],reverse=True)
print(res)

# 需求四:使用 map 映射,把每一个人名加上DSB
names=['lxx','qxx','zhang3','li4']
res=map(lambda name:name + 'DSB',names)
print(list(res))

# 需求五:filter 把所有以sb结尾的换成DSB
names=['lxx_sb','qxx_sb','zhang3_sb','zls','li4_sb']
res=filter(lambda name:name.endswith('sb'),names)
print(list(res))

# 需求六:reduce,把多个值合并成一个结果
from functools import reduce
l=['a','b','c','d']
res=reduce(lambda x,y:x+y,l,'A')
print(res)


# 需求七:reduce,1-100相加
from functools import reduce
res=reduce(lambda x,y:x+y,range(1,101))
print(res)
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-04-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 函数递归介绍
  • 三元表达式
  • 列表生成式\字典生成式\集合生成式
  • 匿名函数
相关产品与服务
运维安全中心(堡垒机)
腾讯云运维安全中心(堡垒机)(Operation and Maintenance Security Center (Bastion Host))可为您的 IT 资产提供代理访问以及智能操作审计服务,为客户构建一套完善的事前预防、事中监控、事后审计安全管理体系,助力企业顺利通过等保测评。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档