一木.溪桥学Python-09:函数的返回值、函数的作用域、作用域的优先级、递归函数、内置文件中常用方法、匿名函数lambda、高阶函数
一木.溪桥 在Logic Education跟Amy学Python
12期:Python基础课
一木.溪桥学Python-09:函数的返回值、作用域、作用域的优先级、递归函数、内置文件中常用方法、匿名函数lambda、高阶函数
日期:2021年1月4日
学习目标:
- 函数的返回值
- 函数的作用域
- 作用域的优先级
- 递归函数
- 内置文件中常用方法
- 匿名函数lambda
- 高阶函数
学习内容:
函数的返回值
当两个函数之间,想要互相使用到内部变量时,就可以应用到函数的返回值。
函数的返回值定义:
tips
使用 return 关键字返回内容
将内容 返回到 函数调用处
函数体中没有 return 语句时,函数运行结束
则默认返回 None , 也被称为隐含返回值表达式:
def function_name(param):
return param
res = function_name(param)eg. :
# 小栗子:
# 摄氏度与华氏度关系如:摄氏度/1.8 + 32 = 华氏度
# 需求:
# 定义函数1:用于输出摄氏度
# 定义函数2:通过摄氏度计算得出华氏度def c_temp():c_t = -3print(f"今天摄氏度:{c_t}℃")return c_tdef f_temp(n):f_t = round(n/1.8) + 30print(f"今天华氏度:{f_t}℉")if __name__ == "__main__":res = c_temp()f_temp(res)
Run:
今天摄氏度:-3℃
今天华氏度:28℉
函数多个返回值
- 当执行函数体内代码时,遇到第一个 return 就将指定值返回到函数调用处,也就是执行到return这行代码,后面的都不执行了。
- 多个返回值时,用逗号隔开,但默认为元组。
- 格式:
def function_name(param1,param2):
return param1
return param2
res = function_name(param)
函数的作用域
作用域介绍
- Python 中,程序的变量并不是在哪个位置都可以访问的,访问权限决定于这个变量是在哪里赋值的。
- 变量的作用域决定了在哪一部分程序可以访问哪个特定的变量名称。Python 的作用域一共有4种,分别是:
L(local):局部作用域,即函数中定义的变量;
E(enclosing):嵌套的父级函数的局部作用域,即包含此函数的上级函数的局部作用域,但不是全局的;
G(global):全局变量,就是模块级别定义的变量;
B(build-in):内建作用域,系统固定模块里面的变量,比如:int()等;
global 关键字
- 当我们需要在函数内部直接修改全局变量时,我们可以将函数内部的局部变量通过 global 关键字声明为全局变量。
函数作用域的优先级
递归函数
递归的介绍
函数Func(args)直接或间接调用函数本身,则该函数称为递归函数。
tips:
递归函数自身没有结束条件,所以需要我们自己设置结束条件,终止函数的调用。
可以使用递归实现的循环都可以实现,并且递归效率很低,所以递归很少使用。
eg. :
# 小栗子:
# 阶乘本质:n! = 1 * 2 * 3 * ... * ndef get_nums(num):if num > 1:return num*get_nums(num - 1)else:return 1res = get_nums(4)
print(res)
Run:
24
内置文件中常用方法
range()
- range(start,stop,step) --> range object
- 步长step不能为小数。(0.5 / 1.5 / …)
-eg. : 实现返回1-10的奇数列表
li = []for i in range(1, 11, 2):li.append(i)print(li)
Run:
[1, 3, 5, 7, 9]
zip()
- zip()用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。
- zip(iter[,iter2 […]]) --> zip object
map()
- map() 会根据提供的函数对指定序列做映射。
- map(func, *iterables) --> map object
filter()
- filter() 用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表。
- filter(func, iterable) --> filter object
匿名函数lambda
匿名函数介绍
- 当我们在传入函数时,有些时候,不需要重复调用该函数,直接传入匿名函数更方便,也无需担心函数名冲突,并且还可以将匿名函数赋值给一个变量,再利用变量来调用该函数。
语法 :lambda x:x*x
匿名函数应用
# lambda 形参:返回值
f = lambda x, y: x * y
print(f(2, 5))
# n!
from functools import reduce
print(reduce(lambda x, y: x*y, range(1, 4)))
# 匿名函数作为返回值
def fx(i, j):# 返回的匿名函数return lambda :i*jf = fx(6, 6) # lambda :i*j
print(f()) # 函数只有在调用时才会执行
# 匿名函数作为实参
def test(a, b, func):res = func(a, b) # 11 + 22return resnums = test(11, 22, lambda x, y: x+y)
print(nums)
Run:33
- sort 与 sorted 区别:
sort 是应用在 list 上的方法,sorted 可以对所有可迭代的对象进行排序操作。
list 的 sort 方法返回的是对已经存在的列表进行操作,无返回值,而内建函数 sorted 方法返回的是一个新的 list,而不是在原来的基础上进行的操作。
# [4,-2,3,1] --> [1,-2,3,4]
# [4,2,3,1] --> [1,2,3,4] --> [1,-2,3,4]
li = [4, -2, 3, 1]# key:指定排序规则,排序之后返回原元素
li.sort(key=abs)
print(li)
高阶函数
- 高阶函数需满足条件:
函数名 作为 参数传入
函数名 作为 返回值
拓展1:值类型与引用类型,传值调用与传引用调用的区别
本段引用来至:值类型与引用类型,传值调用与传引用调用的区别
值类型
- 指基本类型
- 整型: byte,short,int,long
- 浮点型:float,double
- 字符型:char
- 逻辑型:boolean
引用类型
除了四类八种基本类型外,所有的类型都称为引用类型(如:数组,类,接口,字符串)值传递
基本数据类型赋值都属于值传递;
值传递传递的是实实在在的变量值,是传递原参数的拷贝,值传递后,实参传递给形参的值,形参发生改变而不影响实参。特点:
此时内存中存在两个相等的基本类型,即实际参数和形式参数,后面方法中的操作都是对形参这个值的修改,不影响实际参数的值。引用传递
引用类型之间赋值属于引用传递;
引用传递传递的是对象的引用地址,即它的本身;特点:
在方法执行中,形参和实参内容相同,指向同一块内存地址,方法执行中对引用的操作将会影响到实际对象。传值调用
方法调用时,实际参数把它的值的副本传递给对应的形式参数,形参的变化与实参无关。引用调用
方法调用时,实际参数的引用(地址,而不是参数的值)被传递给方法中相对应的形式参数,函数接收的是原始值的内存地址;允许调用函数修改原始变量的值。
拓展2:python中函数值传递与引用传递
本段引用来至:python中函数值传递与引用传递
第一个问题:值传递与引用传递
简单理解,值传递就是在一个参数传入到函数中后,函数中对该参数的操作不会影响函数外该参数的变量的值;而引用传递,则是参数传递进来的相当于内存地址,对该参数的操作会直接影响到外部指向其值的变量。结论
python中的变量没有类型,变量相当于一个指针,可以指向任何类型的对象,也就是变量引用了某个对象;python对象是有类型的,一般看变量是什么类型需要看其引用的对象是什么类型。python中没有严格的定义值传递与引用传递,总的看来,函数传递参数都可以看做是引用传递的(因为python变量相当于指针,传递指针就相当于传递了地址的引用),只不过因为python中的有些对象是不可变的,因此让有些值传递的过程中又像是值传递的。
当python中的函数传递过来的是不可变的值时(比如数字常量、元组和字符串),相当于 C语言中的值传递的;若传递过来的参数是可变的(如列表、字典等),则相当于引用传递。
不可变的对象作参数
看个例子:
x = 10
print("xid=",id(x))
def A(x):print("axid=",id(x))return x
def B(x):x += xreturn x
print("ax=",A(x))
print("bx=",B(x))
print("x=",x)
结果为:
xid= 140718279271088
axid= 140718279271088
ax= 10
bx= 20
x= 10
- 当x传递进函数的时候,会被当作一个局部变量,也就是会新开辟一个空间存放变量,该变量引用了参数的引用。因为原参数引用的是一个不可变的对象,所以局部变量会与函数外的变量指向同一个内存区域;该局部变量不会影响函数外的变量,但在函数内给x重新赋值的时候,会重新生成一个对象,并让局部变量x指向新的对象,而外部变量x不变。因此相当于值传递。
当传递的对象是可变对象时
x = [10]
print("xid=",id(x))
def A(x):print("axid=",id(x))return x
def B(x):x += xreturn x
print("ax=",A(x))
print("bx=",B(x))
print("x=",x)
结果为:
xid= 2769750468232
axid= 2769750468232
ax= [10]
bx= [10, 10]
x= [10, 10]
- 原理与上面的类似,但有区别,x传递进函数仍然可以看作生成了一个局部变量x,其引用了外部变量x的引用,与不变的对象的运算不同的是,此时的x += [10] 操作,不会生成新的列表对象,而是修改了原来存储空间中的列表对象,因此外部的x的值也会跟着改变。
下面的例子与传递不可变参数时是一样的:
x = [10]
print("xid=",id(x))
def A(x):print("axid=",id(x))return x
def B(x):x = [10,10]print("bxid", id(x))return x
print("ax=",A(x))
print("bx=",B(x))
print("x=",x)
结果为:
xid= 2769750458632
axid= 2769750458632
ax= [10]
bxid 2769750460616
bx= [10, 10]
x= [10]
这里是因为赋值号=生成了新的列表导致了局部变量x指向了新的对象,原对象不变。
总结
python中的值传递与引用传递是一个相对的概念,原值有没有变化关键在原来的变量引用的对象有没有发生改变,而这些需要根据变量引用的对象来判断。
作业:
- 作业3
作业答案:
题1:
# 前一次做了!
- Run:
- Amy的答案:
def get_sum(num_a, num_b, num_c):return num_a + num_b + num_cdef get_avg(num_sums, len_li):num_avg = round(num_sums / len_li, 2) # round(object, 2),2代表小数点后精确到位数为2,默认为0.print(f"和为:{num_sums}\n均值为:{num_avg}")if __name__ == "__main__":ipt_li = list(map(float, input("请输入:").split())) # split():拆分字符串。通过指定分隔符对字符串进行切片,并返回分割后的字符串列表(list),默认分隔符为空格num_sums = get_sum(*ipt_li)get_avg(num_sums, len(ipt_li))
-Run:
请输入:45 63 63
和为:171.0
均值为:57.0
题2:
法2:
tips:
- Amy提示的isinstance()真好用呀!get到了!
- 重新认识了 *args 和 *。
- 尝试了用递归没成功,等答案吧!
def opt_tu(*args): # 此处的* 代表可变长度参数前的*print(*args, sep="\n")if __name__ == "__main__":li = ["jack", ("tom", 23), "rose", (14, 55, 67)]for i in range(0, len(li)): # for i in range li:这样更好if isinstance(li[i], tuple): # 测试了也可以这样写 if type(li[i]) == type(()):opt_tu(*li[i]) # 此处的* 代表拆包else:print(li[i])
Run:
jack
tom
23
rose
14
55
67Amy的答案:递归!
def get_ele(l):if isinstance(l, (int, str)):print(l)else:for item in l:get_ele(item)l = ["jack", ("tom", 23), "rose", (14, 55, 67)]get_ele(l)
Run:
jack
tom
23
rose
14
55
67
题3:
infors = [{'name': 'qian', 'age': 28}, {'name': 'amy', 'age': 20}, {'name': 'james', 'age': 25}]print(sorted(infors, key=lambda s: s['name']))
Run:
[{‘name’: ‘amy’, ‘age’: 20}, {‘name’: ‘james’, ‘age’: 25}, {‘name’: ‘qian’, ‘age’: 28}]Amy的答案:
infors = [{'name': 'qian', 'age': 28}, {'name': 'amy', 'age': 20}, {'name': 'james', 'age': 25}]infors.sort(key=lambda x: x["name"])print(infors)
- Run:
[{‘name’: ‘amy’, ‘age’: 20}, {‘name’: ‘james’, ‘age’: 25}, {‘name’: ‘qian’, ‘age’: 28}]
End !
Best wishes for you!
一木.溪桥学Python-09:函数的返回值、函数的作用域、作用域的优先级、递归函数、内置文件中常用方法、匿名函数lambda、高阶函数相关推荐
- python bar函数循环_一木.溪桥学Python-08: for循环、function函数
一木.溪桥 在Logic Education跟Amy学Python 逻辑教育 :https://logicedu.ke.qq.com 12期:Python基础课 一木.溪桥学Python-08: fo ...
- 一木.溪桥学Python-04: Python基础数据类型int ,float ,bool ,complex,None,str, 转义字符
一木.溪桥 在Logic Education跟Amy学Python 12期:Python基础课 一木.溪桥学Python-04: Python基础数据类型int ,float ,bool ,compl ...
- 一木.溪桥学Python-03: Python 运算符
一木.溪桥 在Logic Education跟Amy学Python 12期:Python基础课 一木.溪桥学Python-03: Python 运算符 日期:2020年12月18日 学习目标: 算术. ...
- 一木.溪桥学Python-10:函数闭包、装饰器、推导式
一木.溪桥 在Logic Education跟Amy学Python 逻辑教育 :https://logicedu.ke.qq.com 12期:Python基础课 一木.溪桥学Python-10:函数闭 ...
- 一木.溪桥学Python-06:元组tuple、字典dict
一木.溪桥 在Logic Education跟Amy学Python 12期:Python基础课 一木.溪桥学Python-06:元组tuple.字典dict 日期:2020年12月25日 学习目标: ...
- 一木.溪桥学Python-11:迭代器、生成器、面象对象class MyClass:、self 参数、 __init__() 方法、__str__() 方法
一木.溪桥 在Logic Education跟Amy学Python 逻辑教育 :https://logicedu.ke.qq.com 12期:Python基础课 一木.溪桥学Python-11:迭代器 ...
- 一木.溪桥学Python-13:多继承、多态、常用魔法方法、单例模式
一木.溪桥 在Logic Education跟Amy学Python 逻辑教育 :https://logicedu.ke.qq.com 12期:Python基础课 一木.溪桥学Python-13:多继承 ...
- 一木.溪桥学Python-05: 字符串str、字节bytes、列表list、sort()、sorted()
一木.溪桥 在Logic Education跟Amy学Python 12期:Python基础课 一木.溪桥学Python-05: 字符串str.字节bytes.列表list.sort().sorted ...
- 一木.溪桥学Python-02: 数据类型、标识符、语句与缩进、变量常量、输入input、sep=“ “、end=“\n“
一木.溪桥 在Logic Education跟Amy学Python 12期:Python基础课 一木.溪桥学Python-02: 数据类型.标识符.语句与缩进.变量常量.输入input.sep=&qu ...
最新文章
- DotNetBar12.1新控件——TokenEditor
- Fedora相关(一)
- 修改so_新手向总结:IDA动态调试So的一些坑
- Linux学习之服务器搭建——基础网络配置
- 百度是php写的,百度大秘密,百度也是PHP写的!有证据!千真万确!
- perf之sched
- python之旅-day2(较基础阶段)
- sparkstreaming监听hdfs目录如何终止_四十六、Spark Streaming简介及入门
- [探讨java深入的不变模式] java中String类的用法
- windows 安装python2.7
- 地表温度数据、LST温度数据、地表反照率、NDVI数据、NPP数据、植被覆盖度、土地利用数据
- 什么是HikariCP?HikariCP介绍(包含配置示例)
- spss中有关t检验的详细介绍(包含操作过程和结果分析)
- 专访京东孙海波:大牛架构师养成记及电商供应链中区块链技术的应用
- 解决gitlab内置node_exporter提供外部prometheus使用
- 每个程序员都应该了解的 CPU 高速缓存
- 信号完整性之浅谈理解(七)
- 全国计算机一共几集,夏目友人帐第六季一共多少集?至少11集国内已播出
- Ubuntu18.04解决网卡失效的问题
- 关于flickr的数据集笔记
热门文章
- Java准确获取Word/Excel/PPT/PDF的页数(附Word页数读不准的处理办法)
- 判断x是大写字母的c语言描述,判断字符型变量x是否是大写字母的正确的表达式______....
- 中金公司:资管产品真净值化,摊余成本法还有多少空间?
- CAD.NET 访问天正实体对象
- Python:利用xlwings库实现excel进行插入、删除行操作实例
- [个性化] Vnote 添加预览背景图片以及修改字体等
- 周枫的主战场,有道的新战事
- 【项目问题】PM2管理器运行报错: Error: bind EADDRINUSE null:8360(阿里云服务器)
- 基于java的山水房屋房产中介系统
- 受猪周期跌价影响 天康生物Q3净利亏损4.34亿