推广 热搜: 公司  快速  上海  中国  企业    未来  政策  系统  公司2 

初始Python篇(9)—— 函数

   日期:2024-12-12     作者:gfh5r1    caijiyuan   评论:0    移动:http://www78564.xrbh.cn/mobile/news/30025.html
核心提示:找往期文章包括但不限于本期文章中不懂的知识点: 个人主页:我要学编程(ಥ_ಥ)-CSDN博客所属专栏: Python

找往期文章包括但不限于本期文章中不懂的知识点

初始Python篇(9)—— 函数

个人主页我要学编程(ಥ_ಥ)-CSDN博客

所属专栏 Python

目录

函数的定义及调用

函数的概念 

函数的定义

函数的调用 

水仙花数等自幂数的练习 

函数相关参数的概念 

函数的返回值

变量的作用域 

匿名函数:lambda 

函数递归

常用的内置函数 

数据类型转换函数

数学函数 

迭代器操作函数 

其他函数

课后练习(实战四) 


 

函数是将一段实现功能的完整代码,使用函数名称进行封装,通过函数名称进行调用。以此达到一次编写,多次调用的目的。

函数分为两种:一种是Python的开发人员将带有某些特殊功能的代码封装成函数,这也叫内置函数;另一种是咱们在写代码的时候,自己定义的函数来实现某种功能,这也叫自定义函数。

常见的内置函数:Input、print、eval、math...

语法: 

 

代码演示: 

 

注意:我们自定义的函数并不是直接就可以运行的,要在定义函数的外面去调用它才行。

函数的调用就只需要在 定义函数的外面,去写上该函数的函数名+参数列表即可。

语法

 

代码演示

 

运行结果

有了上述知识,我们可以来写一个稍微复杂一点的函数

要求:求出所有的水仙花数。

水仙花数:是指一个 3 位数,它的每个数位上的数字的 3次幂之和等于它本身。例如:1^3 + 5^3+ 3^3 = 153。 

代码实现

 

当然如果想要拓展的话,可以在原函数的基础上进行传参,从而求出更多的自幂数。

代码实现

 

运行结果

注意:在Python中,有下面这几个关于参数的概念

1、形式参数:定义函数时参数列表中的参数,简称:形参

2、实际参数:在调用函数时,所传输的真实参数,简称:实参

3、位置参数:调用函数时的参数个数与顺序必须与定义的参数个数和顺序一致

例如

 

最后一行代码之所以报错,就是位置参数在作怪,我们传入的参数默认是对应传输的,即按照 name,age 的顺序,如果我们打乱了,就可能会导致代码报错,但是如果参数全部是 字符串类型的话,就不会报错,但是代码的逻辑会出错。 如果我们执意不按顺序传呢?要用到关键字参数。

4、关键字参数:是在函数调用时,使用 "形参名称=值" 的方式进行传参,传递参数顺序可以与定义时参数的顺序不同。因为这相当于是直接对形参赋予相应的值了。还要注意的是,当位置传参与关键字传参一起使用时,得遵循 "位置参数在前,关键字参数在后" 的原则。并且 使用关键字传参时,一定是赋值给形参,因此得写形参的名称,不能写别的。

5、默认值参数:是在函数定义时,直接对形式参数进行赋值,在调用时如果该参数不传值,将使用默认值,如果该参数传值,则使用传递的值。

代码演示

 

既然传参时,有这些顾虑,那在定义函数时,是否也有这些顾虑呢?答案是有的。

代码演示

 

从上面的代码来看,我们可以得出一个结论:当普通形参与带有默认值的形参,一起使用时,默认值形参要放到后面,得让普通形参往前放。因为在赋值时,是按照从前到后的方式赋值的,如果前面已经有默认值的话,再赋值可能并不是我们想要的结果,我们可能只是想给普通形参赋值。

6、可变参数:又分为个数可变的位置参数个数可变的关键字参数两种,其中个数可变的位置参数是在参数前加一颗星(*para,para形式参数的名称,函数调用时可接收任意个数的实际参数,并放到一个元组中。个数可变的关键字参数是在参数前加两颗星(**para,在函数调用时可接收任意多个“参数=值”形式的参数,并放到一个字典中。

位置参数:代码演示

 

 运行结果

关键字参数:代码演示

 

运行结果: 

注意:只有和字典一样的表示形式,才可以使用可变参数中的关键字参数 

前面我们已经简单的学习了函数的定义,并且也为部分函数写了返回值,但是前面的返回值都是单个的返回值,现在我们来学习多变量返回值的实现。

代码演示

 

运行结果

变量的作用域是指变量其作用的范围,根据范围作用的大小可分为局部变量 与 全局变量。

局部变量:在函数定义处的参数与函数内部定义的变量。作用的范围:仅仅在函数内部,函数执行结束,局部变量的生命周期也随之结束。

全局变量:在函数外部定义的变量或者函数内部使用 global 关键字修饰的变量。作用的范围:整个程序,当程序运行结束,全局变量的生命周期才结束。

生命周期:是指某个变量存活的范围内。例如,在函数内部定义的局部变量,其生命周期就是在该函数内部。

代码演示

 
 

当全局变量与局部变量同名时,遵循局部变量优先的原则,即 地头蛇原则:当两个变量同名时,且被调用时,看谁定义的近,谁就其作用。

代码演示

 

 运行结果

注意:全局变量在函数内部直接访问是没问题,但是如果想要在函数内部实现修改的话,就需要在修改其的地方加上 global 关键字。如下所示

修改后的代码

 

这里的 global 相当于 是让 全局变量,对这个函数开放其所有权限。 

匿名函数,是指没有名字的函数,这种函数只能使用一次,一般是在函数的函数体只有一行代码且只有一个返回值时,可以使用匿名函数来简化。 

语法

 

代码演示

 

运行结果

代码演示

 

 运行结果

注意:使用匿名函数时,lambda 会根据 函数体的具体实现来决定是否存在返回值。像,x+1这种函数体,这就是返回了 x+1,但是像,print(x),这种函数体,就没有返回值(或者说为None)。 

函数递归是指,在调用函数体的过程中,出现了自己调用自己的情况。例如,下面这种情况

 

如果我们去尝试运行上面的代码的话,就会出现下面这种情况

如果有学过别的编程语言的小伙伴,应该对这个不陌生。这是 "栈溢出",因为函数每一次调用都需要创建与之对应的栈帧,用于存储当前函数的执行情况(变量的值,执行到哪里了等) ,这份空间是有限的,与内存一样,不可能无限使用。因此当函数调用过多时,就会发生栈溢出的情况。而内存不足,则是会使当前程序启动失败。(这些了解即可

那怎么解决上述问题呢?只需要写出一个正确的递归函数,即需要一个递归的截止条件与递推公式。当函数递归到某个临界点时,不需要再递归了,而是可以直接回退了,这就是递归的截止条件;递推公式,则是需要我们自己去推测出来,后面有例子解释。

递归的两个经典案例:1、阶乘;2、斐波那契数列。

我们先来看阶乘的计算:5! = 5 * 4!,4! = 4 * 3! ... 1! = 1,这里的 1! = 1就是函数递归的截止条件,因为到这里已经无需计算了,而 5! = 5 * 4! 就是函数的递推公式,即 n! = n * (n-1)!。

代码实现

 

我们可以推演一下上述的递归过程。

上图就是计算5的阶乘的全部过程了,大家也可以自己画图来理解递归的过程。

接着来学习 斐波那契数列,相信这个大家都不陌生,我们在数学中是学过这个的。是以兔子繁殖为例子而引入,故又称为“兔子数列",指的是这样—个数列:1、1、2、3、5、8、13、21、34、……从第三项开始,每项都等于前两项之和,这里其实就已经给出了我们斐波那契数列的递推公式了:n <= 2,fib(n) = 1;n >= 3,fib(n) = fib(n-1) + fib(n-2)。

注意:可能有小伙伴见过是0、1、1、2、3、5 .... 这样的说法,这两者都算正确的,但是我们这里讨论的是 1、1 开头的。

代码实现

 

这里的递推过程就不演示了,感兴趣的小伙伴可以自己去画图推演。 

可能有小伙伴,对递归是在是学不明白,没关系,递归最终是为了计算出结果,而能用递归计算出来的结果,都是可以使用循环计算出来的。下面我们来对阶乘与斐波那契数列进行改版。

代码实现

 

运行结果

Python中常用的内置函数,根据功能分类有四种:数据类型转换函数、数学函数、迭代器操作函数、其他函数。

函数名描述bool(obj)获取指定对象obj的布尔值str(obj)将指定对象obj转为字符串类型int(x)将 x 转为 int 类型float(x)将 x 转为 float 类型list(seqence)将序列转成列表类型tuple(sequence)将序列转成元组类型set(sequence)将序列转成集合类型

上述的函数,我们在前面学习的时候,基本上都是用过的,这里就不再演示了。

注意:当字符串的字面值为浮点数时,不能转为 int 类型。int() 在针对 字符串 时,可以理解为只将字符串的引号去掉了,其余的就不管了,因此当字面值为浮点数时,就会转换失败。

函数说明abs(x)获取 x 的绝对值divmod()获取 x 与 y 的商和余数max(sequence)获取 sequence 的最大值min(sequence)获取 sequence 的最小值sum(iter)对可迭代对象进行求和运算pow(x,y)获取 x 的 y 次幂round(x,d)对 x 进行保留 d 位小数,结果是四舍五入

代码演示

 

运行结果

函数说明sorted(iter)对可迭代对象进行排序reversed(sequence)反转序列生成新的迭代器对象zip(iter1,iter2)将iter1与iter2打包成元组并返回一个可迭代的zip对象enumerate(iter)根据iter对象创建一个enumerate对象all(iter)判断可迭代对象iter中所有元素的布尔值是否都为True。如果都为True,则返回True;反之,则返回Falseany(iter)判断可迭代对象iter中所有元素的布尔值是否都为False。如果都为False,则返回False;反之,则返回Truenext(iter)获取迭代器的下一个元素filter(function,iter)通过函数function过滤序列并返回一个迭代器对象map(function,iter)通过函数function对可迭代对象iter的操作返回一个迭代器对象

代码演示

 

运行结果

注意

1、filter 函数 与 map 函数 的第一个参数都是 函数名,这里只需要写函数名,而不需要在后面加上(),加上() 属于调用函数了,不符合要求。

2、可能有小伙伴对最后map的地方有疑惑。有两个 upper ,map是怎么判断使用哪个呢?其实这里涉及到我们后面将要学习的类与对象的知识。我们自己定义的upper 是属于函数的范畴,但是 s.upper 这是属于方法的范畴,虽然两者干的事差不多,但是两者的含义不同。

方法是依附于类而存在的,我们使用方法要么是通过类是调用,要么是通过类的实例去调用。而函数就不一样了,其不依赖于谁,直接使用即可,只需要传参。 

upper(s) —> 这是一个函数,调用只需传参。 s.upper() —> 这是一个方法,调用需要通过实例(这里将s理解为实例)。这里不理解没关系,后面我们会学到的。

其他函数是指这些函数不属于上述分类中的函数。常用的有下面这几种

函数说明format(value,format_spec)将value以format_spec格式进行显示len(s)获取s的长度或者s元素的个数id(obj)获取对象的内存地址type(x)获取x的数据类型eval(s)取出s字符串所对应的字面值

上面的函数除了 format 与 id 之外,其余的都在前面的学习过程中,接触并且使用过,因此这里就不再赘述了。 这里的format函数是对 字符串的format方法的一个补充扩展,为了更好的格式化数据,前面在学习字符串时,format方法只能针对字符串其效果,而这里的format函数是可以对任意数据其作用的。下面这是简单演示一下,具体请看字符串章节。

代码演示

 

运行结果

要求:编写函数实现操作符in的功能。使用input()从键盘获取一个字符串,判断这个字符串在列表中是否存在(函数体不能使用in,返回结果为True或False。

注意:整个函数中不能出现in操作符。

思路:判断字符串是否在列表中存在,肯定是需要去遍历列表的,但是由于不能使用 in 操作符,因此这里就需要用到 while循环。

代码实现: 

本文地址:http://www78564.xrbh.cn/news/30025.html    迅博思语 http://www78564.xrbh.cn/ , 查看更多

特别提示:本信息由相关用户自行提供,真实性未证实,仅供参考。请谨慎采用,风险自负。

 
标签: 函数 参数 代码
 
更多>同类最新资讯
0相关评论

文章列表
相关文章
最新动态
推荐图文
最新资讯
点击排行
网站首页  |  二维码  |  关于我们  |  联系方式  |  使用协议  |  版权隐私  |  网站地图  |  排名推广  |  广告服务  |  积分换礼  |  网站留言  |  RSS订阅  |  违规举报  |  粤ICP备2023022329号