python预习 day14_递归&数学模块&随机模块

递归函数

递归函数: 自己调用自己的函数时递归函数
递:去
归:回

  • 一去一回叫做递归

简单递归

def digui(n):
	print(n,"<===1===>")
	if n > 0 :
		digui(n-1)
	print(n,"<===2===>")
digui(5)	# 543210012345 

代码解析:

  • 去的过程:
n = 5 print(5 , "<===1===>") 5 > 0 digui(5-1) <=> digui(4) <=> 遇到digui(n-1),代码暂停阻塞.
n = 4 print(4 , "<===1===>") 4 > 0 digui(4-1) <=> digui(3) <=> 遇到digui(n-1),代码暂停阻塞.
n = 3 print(3 , "<===1===>") 3 > 0 digui(3-1) <=> digui(2) <=> 遇到digui(n-1),代码暂停阻塞.
n = 2 print(2 , "<===1===>") 2 > 0 digui(2-1) <=> digui(1) <=> 遇到digui(n-1),代码暂停阻塞.
n = 1 print(1 , "<===1===>") 1 > 0 digui(1-1) <=> digui(0) <=> 遇到digui(n-1),代码暂停阻塞.
n = 0 print(0 , "<===1===>") 0 > 0 条件不满足,返回False,不执行
调用,print(0,"<===2===>")
  • 回的过程:
n = 1 从阻塞位置digui(n-1)继续向下执行 print(1,"<===2===>")
n = 2 从阻塞位置digui(n-1)继续向下执行 print(2,"<===2===>")
n = 3 从阻塞位置digui(n-1)继续向下执行 print(3,"<===2===>")
n = 4 从阻塞位置digui(n-1)继续向下执行 print(4,"<===2===>")
n = 5 从阻塞位置digui(n-1)继续向下执行 print(5,"<===2===>")
到此代码全部执行结束   543210012345 

递归函数有回的过程,有两种情况可以触发:

  • (1) 当最后一层函数全部执行结束的时候,有触底反弹的过程(回马枪),回到上层函数空间的调用处
    (2) 遇到return 返回值,直接返回上层空间的调用处

函数在运行的时候,需要内存开辟空间才可以,这个空间叫做栈帧空间

递归:

  • (1)去的过程就是不停的开辟栈帧空间,在回的时候,就是在不停的释放栈帧空间,
    递归函数就是不停的开辟和释放栈帧空间的一个完整的过程
  • (2)回的时候有两种触发的机制,要么是最后一层函数空间全部执行完毕,要么是遇到return,都会触底反弹(回马枪).
  • (3)写递归函数时候,必须给与跳出的条件,如果递归的层数过多,不推荐使用,容易内存溢出或者蓝屏
  • (4)递归调用每一层空间都是独立的个体,独立的副本,资源不共享,可以通过return来完成值的传递.

官方说法,递归最大深度是1000层,具体按照机器来看

递归练习

1.求任意数n的阶乘 : 5! = 5*4*3*2*1

普通写法:

def func(n):
	total = 1
	for i in range(1,n+1):
		total *= i
		"""
		total = total * i => 1 * 1
		total = total * i => 1 * 1 * 2
		total = total * i => 1 * 1 * 2 * 3
		total = total * i => 1 * 1 * 2 * 3 * 4 
		total = total * i => 1 * 1 * 2 * 3 * 4 * 5
		"""
	return total
res = func(5) 
print(res)

递归写法:

def jiecheng(n):
	if n <= 1:
		return 1		
	return n * jiecheng(n-1)
	
res = jiecheng(5)
print(res)
# jiecheng(1) => 1

代码解析:

  • 去的过程:
n = 5  return 5 * jiecheng(5 - 1) => 5*jiecheng(4)
n = 4  return 4 * jiecheng(4 - 1) => 4*jiecheng(3)
n = 3  return 3 * jiecheng(3 - 1) => 3*jiecheng(2)
n = 2  return 2 * jiecheng(2 - 1) => 2*jiecheng(1)
n = 1  return 1
  • 回的过程:
jiecheng(1) = 1
n = 2  return 2*jiecheng(1) => 2*1       [jiecheng(2)]
n = 3  return 3*jiecheng(2) => 3*2*1     [jiecheng(3)]
n = 4  return 4*jiecheng(3) => 4*3*2*1   [jiecheng(4)]
n = 5  return 5*jiecheng(4) => 5*4*3*2*1 [jiecheng(5)]
res = jiecheng(5) <=> 5*4*3*2*1 = 120

尾递归(自己调用自己,并且非表达式)(把值放到参数中运算)(推荐)

无论调用多少次函数,都只占用一份空间
好处: 只需要考虑最后一层空间的结果是多少,就不用额外考虑回的过程了;
cpython解释器目前不支持.

1.阶乘

常规尾递归:

def jiecheng(n,endval):
	if n <= 1:
		return endval	
	return jiecheng(n-1, endval*n)

res = jiecheng(5,1)
print(res)

优化一 (防止用户乱传参数):

def outer(n):
	def jiecheng(n,endval):
		if n <= 1:
			return endval	
		return jiecheng(n-1, endval*n)
	return jiecheng(n,1)
print(outer(5))

优化二 (防止用户乱传参数):

def jiecheng(n,endval=1):
	if n <= 1:
		return endval	
	return jiecheng(n-1, endval*n)
print(jiecheng(5))

代码解析:

  • 去的过程:
n = 5,endval = 1  
	return jiecheng(5-1,endval*n ) => return jiecheng(4,1*5)
n = 4,endval = 1*5
	return jiecheng(4-1,endval*n ) => return jiecheng(3,1*5*4)
n = 3,endval = 1*5*4
	return jiecheng(3-1,endval*n ) => return jiecheng(2,1*5*4*3)
n = 2,endval = 1*5*4*3
	return jiecheng(2-1,endval*n ) => return jiecheng(1,1*5*4*3*2)
n = 1,endval = 1*5*4*3*2
	if 1 <= 1  条件满足 return endval => return 1*5*4*3*2
  • 回的过程:
n = 2  return 1*5*4*3*2
n = 3  return 1*5*4*3*2
n = 4  return 1*5*4*3*2
n = 5  return 1*5*4*3*2
到此程序全部结束;

2.斐波那契数列 用递归 1 1 2 3 5 8 13 …

def feb(n):
	if n ==1 or n == 2:
		return 1
	# 当前值n = 上一个值(n-1) + 上上个值(n-2)
	return feb(n-1) + feb(n-2)

res = feb(5)
print(res)

代码解析:

n = 5 return feb(4) + feb(3) <=> 3 + 2 => 5

		feb(4)          feb(3)
	feb(3) + feb(2)  feb(2) + feb(1)
feb(2)+feb(1)

		feb(4)          feb(3)
	feb(3) + feb(2)  feb(2) + feb(1)
    1+1

		feb(4)          feb(3)
	    2 + 1           1 + 1
		feb(4) = 3      feb(3) = 2

math 数学模块

引入模块:

  • import math

ceil() 向上取整操作【超重点】

res = math.ceil(3.01)
print(res)		# 4

floor() 向下取整操作【超重点】

res = math.floor(4.1)
print(res)		# 4

pow() 计算一个数值的N次方(结果为浮点数) (对比内置pow)

res = math.pow(2,3)
print(res)

sqrt() 开平方运算(结果浮点数)

res = math.sqrt(9)
print(res)

fabs() 计算一个数值的绝对值 (结果浮点数) (对比内置abs)

res = math.fabs(-9)
print(res)

modf() 将一个数值拆分为整数和小数两部分组成元组

res = math.modf(-19.8)
print(res)

copysign() 将参数第二个数值的正负号拷贝给第一个 (返回一个小数)

res = math.copysign(-90,-18)
print(res)# -90.0

fsum() 将一个容器数据中的数据进行求和运算 (结果浮点数)(对比内置sum)

lst = [1,2,3,4]
res = math.fsum(lst)
print(res)

圆周率常数 pi

res = math.pi
print(res)

随机模块 random

引入模块:

  • import random

random() 获取随机0-1之间的小数(左闭右开) 0 <= x < 1**

res = random.random()
print(res)

randrange() 随机获取指定范围内的整数(格式同range) 【超重点】

# 一个参数的用法
res = random.randrange(3) # 0 1 2
# 二个参数的用法
res = random.randrange(3,7) # 3 4 5 6
# 三个参数的用法
res = random.randrange(3,10,2) # 3 5 7 9 
print(res)

randint() 随机产生指定范围内的随机整数(可以取到最大值)【了解 】

res = random.randint(1,3) # 1 2 3
print(res)

uniform() 获取指定范围内的随机小数(左闭右开) 1<=x < 3的小数

res = random.uniform(1,3) 
res = random.uniform(3,1)
print(res)

函数原码:

"Get a random number in the range [a, b) or [a, b] depending on rounding."
return a + (b-a) * self.random()

代码解析:

a = 3 , b = 1
return a + (b-a) * 0~1
return 3 + (1-3) * 0~1
return 3 + -2 * (0~1)

最大值:3 + -2 * 0 = 3
最小值:3 + -2 * 1 = 1

1< x <=3

choice() 随机获取序列中的值(多选一)

lst = ["周杰伦","蔡徐坤","易烊千玺","神秘boy"]
res = random.choice(lst)
print(res)

自定义choice函数:

def mychoice(lst):
	# 随机获取0 ~ 3的下标
	num = random.randrange(len(lst))
	# 通过下标来获取列表的值
	return lst[num]
print(mychoice(lst))

lambda表达式:

mychoice = lambda lst : lst[random.randrange(len(lst))]
print(mychoice(lst))

sample() 随机获取序列中的值(多选多) [返回列表]

lst = ["周杰伦","蔡徐坤","易烊千玺","神秘boy"]
res = random.sample(lst,2)
print(res)

shuffle() 随机打乱序列中的值(直接打乱原序列)

lst = ["周杰伦","蔡徐坤","易烊千玺","神秘boy"]
random.shuffle(lst)
print(lst)

案例:随机验证码 4位 大小写字母数字

chr() => 给ascii码返回对应的字符

# A => 65
# a => 97
print(chr(65)) # A
def yanzhengma():
	strvar = ""
	for i in range(4):
		# 大写字母 A-Z 65~90
		b_word = chr(  random.randrange(65,91)  )
		# 小写字母 a-z 97~122
		s_word = chr(  random.randrange(97,123) )
		# 数字 0 ~ 9
		num = str( random.randrange(10) )
		# 把可能的字符都放在列表里 , 一次抽一个
		lst = [b_word,s_word,num]
		strvar += random.choice(lst)
	return strvar
	
res = yanzhengma()
print(res)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值