day12 函数进阶
一、return作用
- 将数据作为函数的返回值返回
- 结束函数(执行函数体的时候如果遇到return,函数直接结束)
- return只能在函数体中使用
二、变量作用域
1、什么是变量作用域
- 变量作用域指的是变量定义完成以后可以使用的有效范围
- 根据变量作用域的不同可以将变量分为全局变量好局部变量
2、全局变量好和局部变量
1)全局变量
-
python中没有定义在函数中或者类中的变量默认都是全局变量
-
作用域:从定义开始到程序结束
for x in range(5):
print(x)
b=100
# x、b都是全局变量
2)局部变量
-
定义在函数中的变量就是局部变量(形参也是局部变量)
-
局部变量作用域就是从定义开始到函数结束
# m、n都是局部变量
def fun1(m):
n=100
3)为什么?
- 全局变量在定义时就被保存在全局栈区间,只有当程序结束的时候才被销毁,****
- 局部变量是在系统在函数调用中时产生临时栈区间,局部变量被保存在临时栈区间,当函数调用执行结束,保存的数据就被销毁
4)在函数中可以通过关键字global来修改局部变量的保存方式
- 在函数内部定义全局变量用global,然局部变量保存在全局栈
def fun2(m):
global n
n=100
fun2(100)
print(n) # 100
三、匿名函数
1、匿名函数 - 没有函数名的函数
-
函数名 = lambda 形参列表 :返回值
-
相当于:
def 函数名(形参列表):
return 返回值
注意:
- 匿名函数形参至少一个
- 匿名函数的调用和普通函数一样
- 无默认值的类型说明在匿名函数中不能使用
# 定义匿名函数求连个数的和
sum_1 = lambda num1, num2: num2 + num1
print(sum_1(100,200)) # 300
练习:定义一个匿名函数判断指定年是否是闰年
is_runnian=lambda year: (year%4==0 and year%100!=0 )or year%400==0
ressult=is_runnian(2008)
print(ressult)
is_leap_year=lambda year:True if (year%4==0 and year%100!=0 )or year%400==0 else False
ressult=is_leap_year(2008)
print(ressult)
四、实参高阶函数
1、实参高阶函数
- 函数的参数是函数的函数就是实参高阶函数
- 给参数是函数的函数传参:传普通函数的函数名、匿名函数
- 重点:掌握系统或者第三方库提供的实参高阶函数的用法
- 功能强大用法简单
# fun2就是高阶函数
def fun2(x):
x()
def fun3():
print("fun3")
fun2(fun3)
def fun5(x):
print(x(10,20)+12)
# x函数必须有两个形参,且有返回值
fun5(lambda num1,num2:num1+num2)
五、常见的实参高阶函数
1、max、min、sorted、列表.sort
1)max
-
max(序列) - 直接比较序列中元素的大小求最大值
-
max(序列,key=函数) - 按照函数制定的规则比较序列中元素的大小
-
函数的要求:
1)有且只有一个参数(参数代表序列中的每个元素)
2)有一个返回值(返回值就是比较对象)
nums = [10, 30, 66, 33, 90, 77]
print(max(nums))
- 案例:求个位数最大的元素
result = max(nums, key=lambda item: item % 10)
print(result)
- 案例:求nums中绝对值最大的元素
nums = [10, 30, 66, -33, -90, 77]
result = max(nums, key=lambda item: abs(item))
print(result)
- **练习1:**求list1中长度最长的字符串
list1 = ['你好', 'hello', 'how are you', 'thank you! and you?', '好好学习,天天向上']
result = max(list1, key=lambda item: len(item))
print(result)
- **练习2:**求nums中十位数最小的元素
nums = [92, 129, 37, 99, 150, 501]
result = min(nums, key=lambda item: item % 100 // 10)
print(result)
- 练习3:求nums中各个位之和最大的元素
nums = [123, 78, 90, 201, 192, 330]
result = max(nums, key=lambda item: sum([int(x) for x in str(item)]))
print(result)
result = max(nums, key=lambda item: eval('+'.join(str(item))))
print(result)
def sum_of_every(item: int):
sum1 = 0
while True:
if item > 0:
sum1 += item % 10
item = item // 10
else:
return sum1 # 返回值
2、map
- 给予原序列(一个或者多个)中的元素创建一个新的列表
map(函数,序列1)
-
通过函数描述的规则,基于序列中的元素创建一个新的序列
-
函数的要求:
有且只有一个参数(代表后面序列中的每个元素)
有一个返回值(返回值就是新序列中的元素)
map(函数,序列1,序列2)
-
函数的要求:
有且只有两个参数(分别代表后面两个序列中的每个元素)
有一个返回值(返回值就是新序列中的元素 -
案例1:将nums中所有元素乘以10
nums = [123, 78, 90, 201, 192, 330]
result = map(lambda item: item * 10, nums)
print(list(result))
- 案例2:获取nums中所有元素的个位数
nums = [123, 78, 90, 201, 192, 330]
result = map(lambda item: item % 10, nums)
print(list(result))
- 练习1:获取names中每个人的姓
names = ['何晓东', '张三', '李四', '王五', '王二', '赵六']
result = map(lambda item: item[0], names)
print(list(result))
3、reduce
-
将序列中的元素合并成一个数据(基于原序列中所有的元素得到一个数据)
-
reduce(函数,序列,初始值) - 按照函数制定的规则将序列中的元素合并成一个数据
-
函数的要求:
有且仅有两个参数(第一个参数指向初始值,第二个参数指向序列中每个元素)
需要一个返回值(返回值就是合并规则)- 初始值:累计求和:初始值是0
累计求乘积,初始值为1
- 初始值:累计求和:初始值是0
-
from functools import reduce
-
案例:序列元素累计求乘积
nums1 = [123, 78, 90, 201, 192, 330]
result = reduce(lambda initial, item: initial * item, nums1, 1)
print(result)
- 案例:得到1237890201192330
nums1 = [123, 78, 90, 201, 192, 330]
result = reduce(lambda initial, item: initial + str(item), nums1, '')
print(result) # 1237890201192330
- 练习:序列元素个位数之和
nums = [12, 301, 40, 55, 112]
result = reduce(lambda initial, item: initial + item % 10, nums, 0)
print(result)
六、迭代器
1、什么是迭代器(iter)
-
迭代器是容器型数据类型(可以遍历也可以转换成列表)
迭代器不能手动创建,只能将其他序列转换成迭代器
-
特点
打印迭代器时无法查看到元素有哪些
无法通过len获取迭代器中元素的个数
如果要使用迭代器中的元素必须将元素从迭代器中取出来,取走的元素会从迭代器中消失(迭代器中的元素用一个少一个)
-
任何数据都可以作为迭代器的元素**,字典转换从迭代器取的是键作为元素**
-
1)创建迭代器
i1=iter('abc')
i3=iter((10,'sd',True))
- 2)打印迭代器元素
print(i1) # <str_iterator object at 0x00000165608801C0>
- 3)迭代器无法统计个数
# print(len(i1)) # TypeError: object of type 'str_iterator' has no len()
2、获取迭代器中的元素
- 无论以任何方式获取到了迭代器中的某个元素,那么这个元素一定会从迭代器中消失
1)获取单个元素:
-
next(迭代器) - 获取迭代器最上面的元素
-
迭代器为空时取元素会报错
print(next(i1))
print(next(i3))
print(next(i3))
print(list(i3)) # [True]
# print(next(i3)) # 报错 StopIteration
2)遍历迭代器
- for 变量 in 迭代器:
循环体(遍历完迭代器就被掏空了)
i3=iter((10,'sd',True))
for i in i3:
print(i)
print(list(i3)) # []