Python全栈之递归函数

目录
  • 1. 递归函数
  • 2. 递归练习
  • 3. 小练习
  • 总结

1. 递归函数

# ### 递归函数
"""
递归函数 : 自己调用自己的函数 , 叫做递归函数
递 : 去
归 : 回
一去一回叫做递归
"""
def digui(n):
    print(n,"<==1==>")
    if n > 0:
        digui(n-1)
    print(n,"<==2==>")
digui(5)
"""
# 去的过程
n = 5 print(5,"<==1==>")  if 5 > 0:   digui(5-1) =>  digui(4) 代码阻塞在第12行
n = 4 print(4,"<==1==>")  if 4 > 0:   digui(4-1) =>  digui(3) 代码阻塞在第12行
n = 3 print(3,"<==1==>")  if 3 > 0:   digui(3-1) =>  digui(2) 代码阻塞在第12行
n = 2 print(2,"<==1==>")  if 2 > 0:   digui(2-1) =>  digui(1) 代码阻塞在第12行
n = 1 print(1,"<==1==>")  if 1 > 0:   digui(1-1) =>  digui(0) 代码阻塞在第12行
n = 0 print(0,"<==1==>")  if 0 > 0: 不成立 print(0,"<==2==>") 到此最后一层函数空间彻底执行完毕
# 回的过程
回到上一层函数空间  n = 1 代码在第12行的位置,继续往下执行  print(1,"<==2==>")
回到上一层函数空间  n = 2 代码在第12行的位置,继续往下执行  print(2,"<==2==>")
回到上一层函数空间  n = 3 代码在第12行的位置,继续往下执行  print(3,"<==2==>")
回到上一层函数空间  n = 4 代码在第12行的位置,继续往下执行  print(4,"<==2==>")
回到上一层函数空间  n = 5 代码在第12行的位置,继续往下执行  print(5,"<==2==>")
到此递归函数执行结束..
打印 543210012345
"""
"""
每次调用函数时,都要单独在内存当中开辟空间,叫做栈帧空间,以运行函数中的代码
递归总结:
	(1)递归实际上是不停的开辟栈帧空间和释放栈帧空间的过程,开辟就是去的过程,释放就是回的过程
	(2)递归什么时候触发归的过程:
		1.当最后一层栈帧空间执行结束的时候,触发归的过程.
		2.当遇到return返回值的时候终止当前函数,触发归的过程.
	(3)递归不能无限的去开辟空间,可能造成内存溢出,蓝屏死机的情况,所以一定要给予跳出的条件(如果递归的层数太大,不推荐使用)
	(4)开辟的一个个栈帧空间,数据是彼此独立不共享的.
"""
# 递归不能不限开辟空间
"""官方说法最大默认是1000层."""
def deepfunc():
	deepfunc()
deepfunc()

2. 递归练习

# ### 1.使用递归实现任意数n的阶乘
# 普通实现
# 5! =5 *4*3*2*1
n = 5
total = 1
for i in range(n,0,-1):
	total *= i
print(total) # 120
# 递归实现
def jiecheng(n):
	if n <= 1:
		return 1
	return jiecheng(n-1) * n
print(jiecheng(2))
# jiecheng(1) => 1
# jiecheng(2) => jiecheng(1) * 2 => 1 * 2
# jiecheng(3) => jiecheng(2) * 3 => 1 * 2 * 3
# jiecheng(4) => jiecheng(3) * 4 => 1 * 2 * 3 * 4
# jiecheng(5) => jiecheng(4) * 5 => 1 * 2 * 3 * 4 * 5
print(jiecheng(5))
"""
代码解析:
去的过程:
n = 5 return jiecheng(n-1) * n => jiecheng(4) * 5
n = 4 return jiecheng(n-1) * n => jiecheng(3) * 4
n = 3 return jiecheng(n-1) * n => jiecheng(2) * 3
n = 2 return jiecheng(n-1) * n => jiecheng(1) * 2
n = 1 return 1
回的过程:
n = 2 return jiecheng(1) * 2 => 1 * 2
n = 3 return jiecheng(2) * 3 => 1 * 2 * 3
n = 4 return jiecheng(3) * 4 => 1 * 2 * 3 * 4
n = 5 return jiecheng(4) * 5 => 1 * 2 * 3 * 4 * 5
到此程序结束:
返回  1 * 2 * 3 * 4 * 5
"""
print("<====================>")
# ### 2. 使用尾递归来实现任意数的阶乘
""" return 在哪调用,在哪返回 """
"""自己调用自己,且返回时非运算表达式,只是函数本身"""
"""
特点:
	尾递归只开辟一个空间,不会无限的开辟,在一个空间里面去计算最后的结果进行返回,比较节省空间,有的解释器支持尾递归的调用特点
	但是cpython解释器目前不支持
写法:
	所有运算的值都在函数的参数中计算完毕,最后返回运算的参数;
"""
def jiecheng(n,endval):
	if n <= 1:
		return endval
	return jiecheng(n-1 , n * endval)
res = jiecheng(5,1) # 5*4*3*2*1
print(res)
"""
代码解析:
去的过程
n = 5 ,endval = 1 return jiecheng(n-1 , n * endval) => jiecheng(4,5*1) => 5*1*4*3*2
n = 4 ,endval = 5*1 return jiecheng(n-1 , n * endval) => jiecheng(3,5*1*4) => 5*1*4*3*2
n = 3 ,endval = 5*1*4 return jiecheng(n-1 , n * endval) => jiecheng(2,5*1*4*3) => 5*1*4*3*2
n = 2 ,endval = 5*1*4*3 return jiecheng(n-1 , n * endval) => jiecheng(1,5*1*4*3*2) => 5*1*4*3*2
n = 1 ,endval = 5*1*4*3*2   if n <= 1 成立  return endval
endval = 5*1*4*3*2
最下层空间的返回值 是 5*4*3*2*1  最上层接收到的返回值也是 5*4*3*2*1
最下层和最上层返回的结果是一致的,所以对于尾递归来说,只需要考虑去的过程,无需考虑回的过程即可完成;
"""
# 优化代码1
def jiecheng(n,endval=1):
	if n <= 1:
		return endval
	return jiecheng(n-1 , n * endval)
res = jiecheng(5,100) # 5*4*3*2*1
print(res,"<00000>")
# 优化代码2 [把尾递归需要的参数值隐藏起来,避免篡改.]
def outer(n):
	def jiecheng(n,endval=1):
		if n <= 1:
			return endval
		return jiecheng(n-1 , n * endval)
	return jiecheng(n,1)# 120
print(outer(5))
# 优化代码3(扩展)
# 闭包实现
def outer(n):
	endval = 1
	def jiecheng(n):
		nonlocal endval
		if n <= 1:
			return endval
		endval *= n
		return jiecheng(n-1)
	return jiecheng
func = outer(5)
print(func(5),"<===111==>")
print("<================>")
# ### 3.使用递归来完成斐波那契数列
""" 1 1 2 3 5 8 13 21 34 ... """
def feib(n):
	if n == 1 or n == 2:
		return 1
	# 上一个结果 + 上上个结果
	return feib(n-1) + feib(n-2)
print(feib(5))
"""
# 代码解析:
n = 5               feib(5) => 3 + 2 => return 5
		feib(4)        +         feib(3)
    feib(3)+feib(2)          feib(2)+feib(1) => 1 + 1 => 2
feib(2)+feib(1)+feib(2) => 1 + 1 + 1 => 3
"""

3. 小练习

# (选做)
# 1.可滑动的序列 自定义一个函数 根据参数n的值 , 变成对应个元素的容器 (zip)
"""
listvar = [1,2,3,4,5,6,7,8,9]
n = 2
listvar = [[1,2],[3,4],[5,6],[7,8]]
n = 3
listvar = [[1,2,3],[4,5,6],[7,8,9]]
n = 4
listvar = [[1,2,3,4],[5,6,7,8]]
"""
"""
lst1 = [1,3,5,7,9]
lst2 = [2,4,6,8]
zip(lst1,lst2)
"""
listvar = [1,2,3,4,5,6,7,8,9]
n = 2
lst1 = [1,3,5,7,9]
lst2 = [2,4,6,8]
# lst1 = listvar[0::2]  <=> [1,3,5,7,9]
# lst2 = listvar[1::2]  <=> [2,4,6,8]
print(lst2,"1111")
print(list( zip(lst1,lst2) ))
n = 3
lst1 = [1,4,7]
lst2 = [2,5,8]
lst3 = [3,6,9]
# lst1 = listvar[0::3]  <=> [1,4,7]
# lst2 = listvar[1::3]  <=> [2,5,8]
# lst3 = listvar[2::3]  <=> [3,6,9]
print(lst1,"2222")
print(list( zip(lst1,lst2,lst3) ))
n = 4
lst1 = [1,5]
lst2 = [2,6]
lst3 = [3,7]
lst4 = [4,8]
# lst1 = listvar[0::4]  <=> [1,5,9]
# lst2 = listvar[1::4]  <=> [2,6]
# lst3 = listvar[2::4]  <=> [3,7]
# lst4 = listvar[3::4]  <=> [4,8]
print(lst1,"3333")
print(list( zip(lst1,lst2,lst3,lst4) ))
print("<=============>")
n = 3
lst = [ listvar[i::n] for i in range(n) ]
print(lst) # [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
# zip(*lst) => zip([1,4,7],[2,5,8],[3,6,9])
it = zip(*lst)
print(list(it))
func = lambda n : zip(  *[ listvar[i::n] for i in range(n) ]   )
it = func(2)
# 把里面的元组强转成列表
print(list(map(list,it)))
# 2.青蛙跳台阶  (递归实现)
'''
一只青蛙要跳上n层高的台阶
一次能跳一级,也可以跳两级
请问这只青蛙有多少种跳上这个n层高台阶的方法?
n = 1   1 => 1
n = 2   2 => 1 1 | 2
n = 3   3 => 1 1 1 | 1 2 | 2 1
n = 4   5 => 1 1 1 1 | 1 2 1 | 2 1 1 | 1 1 2 | 2 2
n = 5   8 => 1 1 1 1 1 | 1 1 1 2 |2 1 1 1 | 1 2 1 1  | 1 1 2 1 | 2 2 1 | 1 2 2 | 2 1 2
'''
def func(n):
	if n == 1 or n == 2:
		return n
	return func(n-1) + func(n-2)
print(func(5))
# 3.递归反转字符串 "将14235 反转成53241" (递归实现)
# 把后面的字符往前挪动 方法一
strvar = "14235"
# lst.append(5)
# lst.append(3)
# lst.append(2)
# lst.append(4)
# lst.append(1)
# lth = 字符串的总长度  lst 要插入的列表
def func(lth,lst=[]):
	if lth == 0:
		return lst
	res = strvar[lth-1]
	lst.append(res)
	return func(lth-1)
lth = len(strvar)
lst = func(lth)
print(lst) # ['5', '3', '2', '4', '1']
print("".join(lst))
# 简写
def func(lth,lst=[]):
	if lth == 0:
		return "".join(lst)
	res = strvar[lth-1]
	lst.append(res)
	return func(lth-1)
print(func(lth))
# 把前面的字符往后挪动 方法二
strvar = "14235"
def func(strvar):
	if len(strvar) == 1:
		return strvar
	return func(strvar[1:])+strvar[0]
res = func(strvar)
print(res)
"""
递:
return func(4235) + 1
return func(235)  + 4
return func(35)   + 2
return func(5)    + 3
return 5
归:
return func(5)    + 3 => 5 + 3
return func(35)   + 2 => 5 + 3 + 2
return func(235)  + 4 => 5 + 3 + 2 + 4
return func(4235) + 1 => 5 + 3 + 2 + 4 + 1
return 5 + 3 + 2 + 4 + 1
"""

# 4.斐波那契数列用尾递归实现
a,b = 0,1
i = 0
n = 5
while i < n:
	print(b)
	a,b = b,a+b
	i +=1
a,b = 0,1
n = 5
while n > 0:
	print(b)
	a,b = b,a+b
	n -= 1
print("<==============>")
def func(n,a=0,b=1):
	if n == 1:
		return b
	return func(n-1,b,a+b)
print(func(6))

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • python递归函数用法详解

    上期我们介绍了函数式编程,这期内容就是关于递归的函数内容,本期还是按照老规矩,给大家进行核心整理,内容通俗易懂,搭配实际应用,以供大家理解. 关于递归: 百度解释:是指函数/过程/子程序在运行过程序中直接或间接调用自身而产生的重入现象.在计算机编程里,递归指的是一个过程:函数不断引用自身,直到引用的对象已知.使用递归解决问题,思路清晰,代码少.但是在主流高级语言中(如C语言.Pascal语言等)使用递归算法要耗用更多的栈空间,所以在堆栈尺寸受限制时(如嵌入式系统或者内核态编程),应避免采用.所有

  • Python函数递归调用实现原理实例解析

    函数的递归调用: 是函数嵌套调用的一种特殊形式 具体是指: 在调用一个函数的过程中又直接或间接地调用到了本身 # 直接调用本身 def func(): print('我是func') func() func() # 函数会不断的运行永远不会结束,但Python不允许这种情况,会默认限制只能调1000次. # 间接调用本身 def f1(): print('我是f1') f2() def f2(): print('我是f1') f1() f1() # 此时也相当于直接调用本身,f1-->f2-->

  • Python通过递归函数输出嵌套列表元素

    1.先用 for 循环取 for item in l: if isinstance(item ,list): for newitem in item: print(newitem) else: print(item 输出: 1 2 3 4 5 6 #利用 for 循环取值,有几层嵌套就要写几层 for 循环,否则不识别. l=[1,2,[3,4],[5,6,[7,8]]] for item in l: if isinstance(item ,list): for newitem in item:

  • python基础之递归函数

    # 递归满足的条件 # 1.自己调用自己 # 2.必须有一个明确的结束条件 # 优点:逻辑简单\定义简单 # 缺点:防止内存消耗过多,容易导致栈溢出,内存资源紧张,甚至内存泄漏事件发生 # 求阶乘 # 循环的方式去实现 def jiecheng(n): result=1 for item in range(1,n+1): result*=item pass return result #普通函数必须指定返回值 print('4的阶乘为{}'.format(jiecheng(4))) def di

  • Python编程如何在递归函数中使用迭代器

    首先,想要实现的功能是递归遍历文件夹,遇到满足条件的文件时,用yield返回该文件的位置. 如果不用递归器,可以这样实现: path_list = [] def get_one_cage(root: str, cook_folder_name: str): for item in os.listdir(root).copy(): item_path = os.path.join(root, item) if item == cook_folder_name: path_list.append(i

  • Python非单向递归函数如何返回全部结果

    递归( recursion)是一种神奇的编程技巧,可以大幅简化代码,使之看起来更加简洁.然而递归设计却非常抽象,不容易掌握.通常,我们都是自上而下的思考问题, 递归则是自下而上的解决问题--这就是递归看起来不够直观的原因. 和递归相关的概念里,线性递归/非线性递归.单向递归/非单向递归,是非常重要的,要想掌握递归技术,就必须要深入理解.关于递归的基本概念,有兴趣的读者,可以参考我的博客<Python 递归算法指归>.今天,仅就背包问题谈非单向递归函数如何返回全部结果. 背包问题的背后,是世界七

  • python基础学习之递归函数知识总结

    一.递归函数使用注意点 递归函数一定要编写终止条件,否则将产生无限递归.(死循环) 二.递归的效率问题 递归效率不高,递归层次过多会导致栈溢出. Python中不推荐使用递归. 三.递归函数引入 """ 使用代码循环输出故事:从前有座山,山里有座庙... """ # ------------while循环 (暂时忽略死循环)--------------- while True: print("从前有座山,山里有座庙...")

  • Python全栈之递归函数

    目录 1. 递归函数 2. 递归练习 3. 小练习 总结 1. 递归函数 # ### 递归函数 """ 递归函数 : 自己调用自己的函数 , 叫做递归函数 递 : 去 归 : 回 一去一回叫做递归 """ def digui(n): print(n,"<==1==>") if n > 0: digui(n-1) print(n,"<==2==>") digui(5) "

  • python全栈要学什么 python全栈学习路线

    IT行业,技术要比学历.年龄.从业经验更为重要,技术水平直接决定就业薪资,想要学好python,首先要先了解精通Python语言基础.Python web开发.Python爬虫.Python数据分析这四大方面. 全栈即指的是全栈工程师,指掌握多种技能,并能利用多种技能独立完成产品的人.就是与这项技能有关的都会,都能够独立的完成. 全栈只是个概念,也分很多种类.真正的全栈工程师涵盖了web开发.DBA .爬虫 .测试.运维,要学的内容那是相当的巨量.就web开发方向而言需要学习的内容:前端知识 包

  • python全栈知识点总结

    全栈即指的是全栈工程师,指掌握多种技能,并能利用多种技能独立完成产品的人.就是与这项技能有关的都会,都能够独立的完成. 全栈只是个概念,也分很多种类.真正的全栈工程师涵盖了web开发.DBA .爬虫 .测试.运维,要学的内容那是相当的巨量.就web开发方向而言需要学习的内容:前端知识 包括HTML5 CSS3 JS Jquery Ajax,后端至少需要能够熟练使用Django和tornado,当然会flask更好. 扩展资料: 全栈工程师的厉害之处并不是他掌握很多知识,可以一个人干多份工作.而是

  • python全栈开发语法总结

    太多的小伙伴正在学习Python,就说自己以后要做全栈开发,大家知道这是做什么的吗?我们现在所知道的知识点,哪些是以后你要从事这个全栈所需要的呢?从名字上我们可以获知,"全"一样是掌握全部内容,没错,这里就是要自己掌握全部编程技能,足够独立开发的人,因此全栈士不如也说叫"全战士",如果想做,那就看下面能用到的语法吧. 1.中文编码-UTF8字符集 #!/usr/bin/env python # coding:utf8 2.数值 a = 1 b = 2.1 print

  • Python全栈之学习JS(1)

    目录 1. js的数据类型 1.1 js引入方式 1.2 注释变量 1.3 数据类型 2. js类型转换_运算符 2.1 强制转换_Number 2.2 强制转换_String 2.3 强制转换_Boolean 2.4 自动类型转换_Number_Boolean_String三者之间转换 2.5 js运算符 3. js流程控制 3.1 分支结构 3.2 分支结构_switch_case 3.3 循环结构 4. js函数 4.1 函数 4.2 函数的调用 总结 1. js的数据类型 1.1 js引

  • Python全栈之列表数据类型详解

    前言 列表(list)同字符串一样都是有序的,因为他们都可以通过切片和索引进行数据访问,且列表是可变的. 创建列表的几种方法 第一种 name_list = ['Python', 'PHP', 'JAVA'] 第二种 name_list = list(['Python', 'PHP', 'JAVA']) 创建一个空列表 >>> li = list() >>> type(li) <class 'list'> 把一个字符串转换成一个列表 >>>

  • Python全栈之面向对象基础

    目录 1. 面向对象oop了解 2. 对象的相关操作 小提示: 3. 类的相关操作 4. 类对象的删除操作 小提示: 5. 小练习 小提示: 答案: 总结 1. 面向对象oop了解 # ### oop 面向对象的程序开发 # (1) 类的定义 # 1 class Car: pass # 2 推荐 class Car(): pass # 3. class Car(object): pass # (2)类的实例化 class Car(): pass obj = Car() print(obj) #

  • Python全栈之单项循环

    目录 1. 多项_巢状分支 2. 循环结构 2.1 循环结构 2.2 单项循环的练习 3. 字符串的切片 4. 小练习 问题: 答案: 总结 1. 多项_巢状分支 2. 循环结构 2.1 循环结构 2.2 单项循环的练习 3. 字符串的切片 4. 小练习 问题: 答案: 总结 1. 多项_巢状分支 多项分支 (多选一) """ if 条件表达式1: code1 elif 条件表达式2: code2 elif 条件表达式3: code3 else: `code4 如果条件表达式

  • Python全栈之运算符详解

    目录 1. 算数_比较_赋值_成员 1.1 算数运算符 1.2 比较运算符 1.3 赋值运算符 1.4 成员运算符 2. 身份运算符 小提示: 3. 逻辑运算符 3.1 位运算符 3.2 小总结 4. 代码块_单项_双项分支 4.1 代码块 4.2 流程控制 4.3 单项分支 4.4 双项分支 5. 小作业 总结 1. 算数_比较_赋值_成员 1.1 算数运算符 算数运算符: + - * / // % ** # + var1 = 7 var2 = 90 res = var1 + var2 pri

  • Python全栈之字符串和列表相关操作

    目录 1. format格式化_填充符号使用 1.1 format格式化 1.2 format的填充符号的使用 2. 字符串相关的方法 3. 列表的相关操作 4. 列表的相关函数 5. 深浅拷贝 小提示: 6. 小练习 (1)字符串相关练习问题: (2)列表相关练习问题: 总结 1. format格式化_填充符号使用 1.1 format格式化 字符串的格式化format # (1)顺序传参 """{}是format中的占位符""" strvar

随机推荐