1.函数
1.1 函数概述
- 函数定义和优势
- 不同形状正方形打印
# 2个
for i in range(0, 2):for j in range(0, 2):print("*", end="")print()
# 3个
for i in range(0, 3):for j in range(0, 3):print("*", end="")print()
# 4个
for i in range(0, 4):for j in range(0, 4):print("*", end="")print()
- 改写后:
# 定义函数,函数名称为print_xx
def print_xx(x):for i in range(0, x):for j in range(0, x):print("*", end="")print("")# 函数调用
print_xx(2)
print_xx(3)
print_xx(4)
- 优点有哪些?
1.2 函数定义和调用
函数定义
函数调用
-
格式:函数名([参数列表])
-
调用过程:
- 程序在调用函数的位置暂停执行。
- 将数据传递给函数参数。
- 执行函数体中的语句。
- 程序回到暂停处继续执行。
作业1:改写
- 改写平均数成def
- 改写闰年判断
# 改写平均数练习,要求是三个数字的平均数
# 定义求平均数的函数
def avg_input(x, y, z):avg = (x + y + z) / 3print(f"平均数是:{avg}")# 定义判断闰年的函数
def judge_rn(year):# 1.能被400整除if year % 400 == 0:print(f"{year}是闰年")# 2.能被4整除但不能被100整除elif year % 4 == 0 and year % 100 != 0:print(f"{year}是闰年")else:print(f"{year}不是闰年")judge_rn(2008)
print("----------")
# 调用函数
avg_input(1, 2, 3)
print("----------")
# a = eval(input("a="))
# b = eval(input("b="))
# c = eval(input("c="))
# avg_input(a, b, c)
1.3 参数传递
- 形参:定义函数时的参数
- 实参:调用函数时使用的参数
- 参数传递:实参——>形参
位置参数传递:
- 概念:第一个实参传递给第一个形参,将第二个实参传递给第二个形参
关键字参数传递:
- 概念:调用函数(形参=实参)形式
默认参数传递:
- 默认参数:指的是形参的默认值
参数的打包与解包
打包
-
函数在定义时无法确定需要接收多少个数据,那么可以在定义函数时为形参添加“”或“**”:
-
*—— 接收以元组形式打包的多个值
-
#定义 def test(*args):print(args) #调用 test(11, 22, 33, 44, 55) #结果 #(11, 22, 33, 44, 55)
-
**—— 接收以字典形式打包的多个值
-
#定义 def test(**kwargs):print(kwargs) #调用 test(a=11, b=22, c=33, d=44, e=55) #结果 #{'a': 11, 'b': 22, 'c': 33, 'd': 44, 'e': 55}
-
解包
-
实参是元组 → 可以使用“*”拆分成多个值 → 按位置参数传给形参
-
形参已经知道有多少个参数
-
#定义 def test(a, b, c, d, e):print(a, b, c, d, e) #调用 nums = (11, 22, 33, 44, 55) test(*nums) #结果 #{'a': 11, 'b': 22, 'c': 311 22 33 44 553, 'd': 44, 'e': 55}
-
-
实参是字典 → 可以使用“**” 拆分成多个键值对 → 按关键字参数传给形参
-
#定义 def test(a, b, c, d, e):print(a, b, c, d, e)#函数调用 nums = {"a":11, "b":22, "c":33, "d":44, "e":55} test(**nums) #结果 #11 22 33 44 55
-
作业2:
# 平均数:计算n个参数的平均值
# 定义函数计算平均值
def avg_input(*args):sum = 0for i in args:sum += iavg = sum / len(args)print(f"和是{sum},有{len(args)}个数字,平均值是:{avg}")avg_input(1)
avg_input(1, 2)
avg_input(1, 2, 3)
avg_input(1, 2, 3, 4)
作业3:
# 从键盘一直获取数字,当输入0000退出,
# 计算之前获取的值的平均值def avg_input(mylist):sum = 0for i in mylist:sum += iavg = sum / len(mylist)print(f"和是{sum},有{len(mylist)}个数字,平均值是:{avg}")def gain_input():# 1. 从键盘一直获取数字,当输入0000退出while (True):# #int()转化为整数数字# x = int(input("请输入数字:"))x = eval(input("请输入数字:"))if x == 0000:breakelse:# list_nums.insert(0, x)list_nums.append(x)list_nums = []
gain_input()
print(list_nums)
# 2. 计算之前获取的值的平均值
avg_input(list_nums)
混合传递
-
优先级:
- 优先按位置参数传递的方式。
- 然后按关键字参数传递的方式。
- 之后按默认参数传递的方式。
- 最后按打包传递的方式。
-
注意事项
在定义函数时: 带有默认值的参数必须位于普通参数之后。 带有“*”标识的参数必须位于带有默认值的参数之后。 带有“**”标识的参数必须位于带有“*”标识的参数之后
作业4:
1.4 函数的返回值
-
return函数:
-
# 屏蔽关键字这个功能 def filter_key(str):# 2 使用字符串的替换功能,把要替换关键字替换为目标对象str = str.replace("山寨", "**")return str# 1 准备一个字符串 key = "手机的山寨的!" # 调用过滤函数 key = filter_key(key) # 3 打印替换后的结果 print("key=", key)
#函数定义 def move(x, y, step):nx = x + stepny = y - stepreturn nx, ny # 使用return语句返回多个值 #函数调用 result = move(100, 100, 60) print(result) #结果 #(160, 40)
作业1:
- 使用正则表达式完成屏蔽关键字的功能
1.5 变量作用域
- 概念:其访问权限取决于变量定义的位置,其所处的有效范围称为变量的作用域。
1.5.1 局部变量
-
定义位置:在函数内部
-
特点:
- 只能在函数内部被使用
- 函数执行结束后,无法再进行访问
-
def test_one():number = 10 # 局部变量print(number) # 函数内部访问局部变量 test_one() print(number) # 函数外部访问局部变量
-
不同函数内部可以包含同名的局部变量
-
def test_one():number = 10 print(number) # 访问test_one()函数的局部变量number def test_two():number = 20print(number) # 访问test_two()函数的局部变量number test_one() test_two()
-
1.5.1 全局变量
- 定义位置:函数外面,单独定义
number = 10 # 全局变量
def test_one():print(number) # 函数内部访问全局变量
test_one()
print(number) # 函数外部访问全局变量
- 特点:全局变量在函数内部只能被访问,无法直接修改
# 定义全局变量
number = 10
def test_one():numberprint(number) number += 1
test_one()
print(number)
1.5.1 关键字global和nonlocal
- (掌握)global关键字可以将局部变量声明为全局变量
number = 10 # 定义全局变量
def test_one():global number # 使用global声明变量number为全局变量number += 1print(number)
test_one()
print(number)
- (了解)nonlocal关键字:局部作用域中修改嵌套作用域中定义的变量
def test():number = 10def test_in():nonlocal numbernumber = 20test_in()print(number)
test()
作业2:
- 练习以上PPT案例:从变量 作用域开始,到global关键字结束
1.6 实训案例
-
角谷猜想
-
以一个正整数n为例,如果n为偶数,就将它变为n/2,如果除后变为奇数,则将它乘3加1(即3n+1)。不断重复这样的运算,经过有限步后,必然会得到1。 本实例要求编写代码,计算用户输入的数据按照以上规律经多少次运算后可变为1。
def guess_nums(guess):i = 0 # 统计重复多少次# 2 按照规则重复进行,=1 不再重复while (guess != 1):i += 1if guess % 2 == 0:guess /= 2else:guess = 3*guess+1# 3 打印结果print(f"经过{i}次得到1")# 1 获取用户输入输入的数据 x = eval(input("x=")) # 调用函数 guess_nums(x)
# 全局变量
dict_goods = {"可口可乐": 2.5, "百事可乐": 3, "健力宝": 5}
# 展示功能def show():print("饮品自动售货机")# 展示商品for key, value in dict_goods.items():print(f"{key}:{value}元")print("输入q完成购买")# 购买功能def buy():money = 0x = input("请输入购物的商品:")# 省略步骤判断输入的商品在不在货架上# 计算金额while (x != "q"):count = eval(input("请输入购物的数量:"))# 计算金钱money += dict_goods[x] * count# 下次的购物商品x = input("请输入购物的商品:")print(f"需要支付金额{money}元")# 函数调用
show()
buy()
1.7 特殊函数
1.7.1 递归函数
-
概念:函数自己调用自己
-
格式:
-
#阶乘案例: def func(num):if num == 1: return 1else:return num * func(num - 1) num = int(input("请输入一个整数:")) result = func(num) print("5!=%d"%result)
1.7.2 匿名函数
概念:
-
关键字lambda来创建,并可以赋给一个变量供调用,没有名字的函数。
-
用于定义简单的、能够在一行内表示的函数
示例:
sum = lambda a,b=100:a+b #允许带默认参数
print("变量之和为:",sum(100,200))
print("变量之和为:",sum(100))#下面是等价形式:
def sum_nums(a,b=100):return a+b
print("变量之和为:",sum_nums(100,200))
print("变量之和为:",sum_nums(100))
1.7.3 特殊函数
-
map函数
-
功能:单参数函数依次作用到一个序列对象的每个元素
-
案例:
-
#示例: #定义函数sqr(x) def sqr(x):return x**2 #列表 item1=[1,2,3,4,5] #使用map函数 for i in map(sqr,item1): print(i,end=' ') #结果 #1 4 9 16 25
-
-
reduce函数
-
功能:用传给 reduce 中的函数 function(有两个参数)先对集合中的第 1、2 个元素进行操作,得到的结果再与第三个数据用 function 函数运算,以此类推,最后得到一个结果
-
from functools import reduce #需要导入模板 def add(x,y):return x+y print("累加结果:",end=' ') print(reduce(add, [1,2,3,4])) #结果10
-
filter函数
-
功能:,其作用是将一个单参数函数作用到一个序列上,返回该序列中使得该函数返回值为True的那些元素组成的列表、元组或字符串
-
#定义函数判断奇数 def is_odd(n):return n%2==1 newlist1 = filter(is_odd,range(1,11)) #通过自定义函数构造过滤器 print("奇数序列为:",end=' ') for i in newlist1:print(i,end=' ') #奇数序列为: 1 3 5 7 9
-