一木.溪桥 在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:值类型与引用类型,传值调用与传引用调用的区别

本段引用来至:值类型与引用类型,传值调用与传引用调用的区别

值类型
  • 指基本类型
  1. 整型: byte,short,int,long
  2. 浮点型:float,double
  3. 字符型:char
  4. 逻辑型: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
    67

  • Amy的答案:递归!

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、高阶函数相关推荐

  1. python bar函数循环_一木.溪桥学Python-08: for循环、function函数

    一木.溪桥 在Logic Education跟Amy学Python 逻辑教育 :https://logicedu.ke.qq.com 12期:Python基础课 一木.溪桥学Python-08: fo ...

  2. 一木.溪桥学Python-04: Python基础数据类型int ,float ,bool ,complex,None,str, 转义字符

    一木.溪桥 在Logic Education跟Amy学Python 12期:Python基础课 一木.溪桥学Python-04: Python基础数据类型int ,float ,bool ,compl ...

  3. 一木.溪桥学Python-03: Python 运算符

    一木.溪桥 在Logic Education跟Amy学Python 12期:Python基础课 一木.溪桥学Python-03: Python 运算符 日期:2020年12月18日 学习目标: 算术. ...

  4. 一木.溪桥学Python-10:函数闭包、装饰器、推导式

    一木.溪桥 在Logic Education跟Amy学Python 逻辑教育 :https://logicedu.ke.qq.com 12期:Python基础课 一木.溪桥学Python-10:函数闭 ...

  5. 一木.溪桥学Python-06:元组tuple、字典dict

    一木.溪桥 在Logic Education跟Amy学Python 12期:Python基础课 一木.溪桥学Python-06:元组tuple.字典dict 日期:2020年12月25日 学习目标: ...

  6. 一木.溪桥学Python-11:迭代器、生成器、面象对象class MyClass:、self 参数、 __init__() 方法、__str__() 方法

    一木.溪桥 在Logic Education跟Amy学Python 逻辑教育 :https://logicedu.ke.qq.com 12期:Python基础课 一木.溪桥学Python-11:迭代器 ...

  7. 一木.溪桥学Python-13:多继承、多态、常用魔法方法、单例模式

    一木.溪桥 在Logic Education跟Amy学Python 逻辑教育 :https://logicedu.ke.qq.com 12期:Python基础课 一木.溪桥学Python-13:多继承 ...

  8. 一木.溪桥学Python-05: 字符串str、字节bytes、列表list、sort()、sorted()

    一木.溪桥 在Logic Education跟Amy学Python 12期:Python基础课 一木.溪桥学Python-05: 字符串str.字节bytes.列表list.sort().sorted ...

  9. 一木.溪桥学Python-02: 数据类型、标识符、语句与缩进、变量常量、输入input、sep=“ “、end=“\n“

    一木.溪桥 在Logic Education跟Amy学Python 12期:Python基础课 一木.溪桥学Python-02: 数据类型.标识符.语句与缩进.变量常量.输入input.sep=&qu ...

最新文章

  1. DotNetBar12.1新控件——TokenEditor
  2. Fedora相关(一)
  3. 修改so_新手向总结:IDA动态调试So的一些坑
  4. Linux学习之服务器搭建——基础网络配置
  5. 百度是php写的,百度大秘密,百度也是PHP写的!有证据!千真万确!
  6. perf之sched
  7. python之旅-day2(较基础阶段)
  8. sparkstreaming监听hdfs目录如何终止_四十六、Spark Streaming简介及入门
  9. [探讨java深入的不变模式] java中String类的用法
  10. windows 安装python2.7
  11. 地表温度数据、LST温度数据、地表反照率、NDVI数据、NPP数据、植被覆盖度、土地利用数据
  12. 什么是HikariCP?HikariCP介绍(包含配置示例)
  13. spss中有关t检验的详细介绍(包含操作过程和结果分析)
  14. 专访京东孙海波:大牛架构师养成记及电商供应链中区块链技术的应用
  15. 解决gitlab内置node_exporter提供外部prometheus使用
  16. 每个程序员都应该了解的 CPU 高速缓存
  17. 信号完整性之浅谈理解(七)
  18. 全国计算机一共几集,夏目友人帐第六季一共多少集?至少11集国内已播出
  19. Ubuntu18.04解决网卡失效的问题
  20. 关于flickr的数据集笔记

热门文章

  1. Java准确获取Word/Excel/PPT/PDF的页数(附Word页数读不准的处理办法)
  2. 判断x是大写字母的c语言描述,判断字符型变量x是否是大写字母的正确的表达式______....
  3. 中金公司:资管产品真净值化,摊余成本法还有多少空间?
  4. CAD.NET 访问天正实体对象
  5. Python:利用xlwings库实现excel进行插入、删除行操作实例
  6. [个性化] Vnote 添加预览背景图片以及修改字体等
  7. 周枫的主战场,有道的新战事
  8. 【项目问题】PM2管理器运行报错: Error: bind EADDRINUSE null:8360(阿里云服务器)
  9. 基于java的山水房屋房产中介系统
  10. 受猪周期跌价影响 天康生物Q3净利亏损4.34亿