Day09 函数2

函数的返回值

写函数的目的就是希望封装好这个程序,后续随时调用,函数不写return,就不能得到函数的返回值,这样我们函数写出来就达不到我们的预期。

例如:定义函数:
def fun1():
    return 1

调用函数:
print(fun1())

运行结果: 1

返回值的类型

任何类型的值都可以作为函数的返回值来返回
包括:常用的数据类型,甚至是函数都可以作为返回值返回

return 1     #返回整型
return None  #返回空值
return fun2  #返回函数
return       #如果return后不写东西就是返回None
若函数中不写return语句,其实函数返回的也是None

Return特性

函数中,return后面的代码都不会执行了,一旦return函数就自动结束了。与break的用法有点相似,但比break还绝,break只是中断本层循环,不影响外层循环。

函数说明文档

运用于对函数或者面向对象做功能、参数等的说明帮助文档
采用长文本注释方式写大段说明文字:即用三个引号括起来

例如:
def fun(a, b):
    """
    这是一个文档字符串的示例
    这个函数的功能是做什么。。。。。
    函数的参数:
    :param  a : 作用  功能  类型  默认值
    :param  b :作用  功能  类型  默认值
    :return : 需要
    """

函数作用域

在函数外面的变量都是全局变量,可以在函数里面使用
函数里面的变量不能拿到函数外部使用,因这个变量是局部变量,
可以使用global声明此变量是全局变量

b = 456  # 函数外,所以b是全局变量,可在本程序中任意使用b变量
def fun():
    a = 123  # 函数内,所以a是局部变量,在函数外无法用a变量
    print('函数内部', a)
    print('函数内部', b)

fun()
print('函数外部打印b变量的值', b)
# print('函数外部打印a变量的值', a)  #这语句会报错,函数外无法使用函数内的局部变量

命名空间

命名空间实际上就是一个字典,是一个专门用来存储变量的字典
locals()用来获取当前作用域的命名空间
如果在全局作用域中调用locals()则获取全局命名空间,如果在函数作用域中调用locals()则获取函数命名空间
返回值是一个字典

递归函数

递归是解决问题的一种方式,它的整体思想,是将一个大问题分解为一个个的小问题,直到问题无法分解时,在去解决问题,这种思想挺重要的!!!
递归式函数有2个条件
基线条件 问题可以被分解为最小问题,当满足基线条件时,递归就不执行了
递归条件 可以将问题继续分解的条件
我们来看一个需求,逐步理解递归

需求: 求10! 求10的阶乘

分析10的阶乘

1! = 1
2! = 1*2
3! = 1*2*3
4! = 1*2*3*4
>>>>
10!= 1*2*3*4*5*6*7*8*9*10

最简单的方法就是直接输出,如:print(123456789*10),但是此方法显得有点low,而且对后期更改不方便,如果我要一个99的阶乘怎么办,还得一个一个去敲对吧!

# 用循环写法
n = 10
for i in range(1, n):
    n *= i
print(n)
运行结果 》》》3628800

相对于直接输出,用循环也可以,这样简单多了,只用更改n的值,我们就可以得到不同数的阶乘

# 封装函数
def fun(n):
    for i in range(1, n):
        n *= i
    return n

r = fun(10)
print(r)
运行结果 》》》3628800

都说到这了,似乎还是没有将关于递归的知识,不要慌,马上就到!
递归函数: 首先他是一个函数 , 他是一个自己调用自己的函数,跟死循环极相似,所以同样函数如果没有加上退出条件,就会造成无穷递归,所以一定要写条件,使函数不在调用自己。

条件分2个 :
1、基线条件:问题可以被分解为最小的问题,当满足基线条件的时候,我们再去解决问题
2、递归条件: 将问题继续分解的条件

# 无穷递归
def fun1():
    fun1()
fun1()

讲了递归的怎么多概念之后,我们开始回到我们的需求,求10!

# 需求: 求10!   求10的阶乘
1= 1
2! = 1*2
3! = 1*2*3
>>>>
10!= 1*2*3*4*5*6*7*8*9*10

10= 10*99= 9*88= 8*7>>>>
1= 1

这里我们就将这个划分,过程中我们就能找到规律,n! = n*(n-1)!,以此得到递归条件n * fun(n-1),到最小的1!无法分解,我们以此就能得到基线条件n == 1

def fun(n):      # 求n!
    # 基线条件  让递归停止运行的条件
    if n == 1:
        return 1

    # 递归条件
    return n * fun(n-1)
    
r = fun(10)  
print(r)
运行结果 》》》3628800

以上就是求阶乘的递归函数的全过程,如果一次看不懂,多看看相关的题目,肯定可以搞懂的!!!

作业

1.用函数实现一个判断用户输入的年份是否是闰年的程序

# 闰年年份特征:1)能被400整除的年份,2)或者能被4整除,但是不能被100整除的年份
def leapYear(y):
    if y % 400 == 0:
        print(f"年份{y}是闰年")
    elif y % 4 == 0 and y % 100 != 0:
        print(f"年份{y}是闰年")
    else:
        print(f"年份{y}不是闰年")

leapYear(int(input('请输入要判断是否为闰年的年份:')))

2.猴子第一天摘下若干个桃子,当即吃了一半,还不瘾,又多吃了一个。第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩的一半零一个。到第10天早上想再吃时,见只剩下一个桃子了,求第一天共摘了多少桃子?

# 分析:
'''
第一天 剩: n/2-1
第二天 剩: (n/2-1)/2-1 > n/4-3/2
第三天 剩: (n/4-3/2)/2-1 > n/8-7/4
...
第十天 剩: 1个

第十天   剩:1个
第九天   剩:(1+1)*2=4个
第八天   剩:(4+1)*2=10个
...
'''
# 循环写法:
i=1
for j in range(1,10):
  i=(i+1)*2
print(f'共摘了{i}个桃子')
# 运行结果: 共摘了1534个桃子

# 递归写法:
def fun1(n):
    # 基线条件
    if n==10:
        return 1
    # 递归条件
    return (fun1(n+1)+1)*2

print(f'共摘了{fun1(1)}个桃子')
# 运行结果: 共摘了1534个桃子
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值