第五章.python函数

文章目录

1.函数的定义及调用

  • 函数:函数是将一段实现功能的完整代码,使用函数名进行封装,通过函数名称进行调用.以此达到一次编写,多次调用的目的
    • 内置函数:
      • 输出函数print()
      • 输入函数input()
      • 列表定义函数list()
    • 自定义函数:
      • def 函数名称(参数列表): 函数体 [return 返回值列表]
      • 使用关键字def
      • 确定函数名称,参数名称,参数个数,编写函数体(用于实现函数功能的代码)
    • 函数调用:
      • 函数名(参数列表)
      • 通过函数名称进行调用函数
      • 对函数的哥哥参数进行实际的赋值
    • 函数的执行:
      • 使用实际参数参与函数功能的实现
    • 函数返回结果:
      • 函数执行结束后,如果使用return进行返回结果,则结果被返回到函数的调用处
python 复制代码
def get_sum(n):# n 为形式参数
    s=0
    for i in range(1,n+1):
        s+=i
    print(f'1到{n}之间的累加和:{s}')

get_sum(10) # 实际参数
get_sum(12)

2.函数的参数传递

  • 位置参数
    • 指调用时的参数个数和顺序必须与定义的参数个数和顺序相同
python 复制代码
def happy(name,age):
    print("祝"+name+"生日快乐")
    print(str(age)+"岁生日快乐")

# happy("哈哈")#TypeError: happy() missing 1 required positional argument: 'age'
#happy(1,"哈哈")# TypeError: can only concatenate str (not "int") to str
happy("哈哈",1)
  • 关键字参数
    • 是在调用函数时,使用"形式名称=值"的方式进行传参,传递参数顺序可以与定义时参数的顺序不同
python 复制代码
def happy(name,age):
    print("祝"+name+"生日快乐")
    print(str(age)+"岁生日快乐")

#关键字传参
# happy(age=12,name="呵呵")
# happy(age=12,name1="呵呵")#定义的形参和调用时传入的参数必须一样

#即使用 位置传参 又使用 关键字传参
happy("呵呵",age=1)
#是否可以顺序颠倒
#不可以,违反了 位置参数在前,关键字参数在后的一个规则
# happy(name="呵呵",1)# SyntaxError: positional argument follows keyword argument
  • 默认值参数
  • 是在函数定义时,直接对形式参数进行赋值,在调用时如果该参数不传值,将使用默认值,如果该参数传值,则使用传递的值
python 复制代码
def happy(name="哈哈",age=1):
    print("祝"+name+"生日快乐")
    print(str(age)+"岁生日快乐")

# happy() #不用传参
# happy("呵呵") # 位置传参
# happy(12)#报错 使用位置传参传给了name
# TypeError: can only concatenate str (not "int") to str
happy(age=12)
# 函数定义时,默认参数在最后

def fun(a,b=1): #a作为位置参数,b为默认值
    pass

def fun(a=1,b): #报错
#当位置参数和默认值参数同时存在的时候,位置参数在后会被报错
    pass
#当位置参数和关键字参数同时存在时,应该遵循 位置参数在前 , 默认参数在后
  • 可变参数:
    • 1.个数可变的位置参数:
      • 在参数前加一颗星(*para),para形式参数的名称,函数调用时可接收任意个数的实际参数,并放到一个元祖中
    • 2.个数可变的关键字参数:
      • 在参数前加两颗星(**para),在函数调用时可接收任意多个"参数=值"形式的参数,并放到一个字典中.
python 复制代码
# 1.个数可变的位置参数
def fun(*para):
    print(type(para))
    for item in para:
        print(item)
fun(1,2,3,4,4)
fun(1)
fun([1,2,3,4]) #实际上传递的是一个参数
#分开传递的办法,在调用时,参数前加一颗星,将列表进行解包
fun(*[1,2,3,4,5])

# 2.个数可变的关键字参数
def fun1(**kwpara):
     print(type(kwpara))
     for key,value in kwpara.items():
         print(key,"********",value)

fun1(name="11",age=22,height=123) #关键字参数

d={'name':"11",'age':'22','height':'123'}
fun1(**d)  #系列解包操作
  • 函数的返回值
    • 如果函数的运行结果需要在其他函数中使用,那么这个函数就应该被定义为带返回值的函数
    • 函数的运行结果使用return关键字进行返回
    • return可以出现在函数中的任意一个位置,用于结束函数
    • 返回值可以是一个值,或多个值,如果返回的值是多个,结果是一个元祖类型
python 复制代码
def fun(a,b):
    print(a+b)


fun(1,2)
print(fun(1,2))#None

def fun2(a,b):
    s=a+b
    return s

print("-"*10)
get_s = fun2(1,2)
print(get_s)

#多个返回值
def get_sum(num):
    s=0
    odd_sum=0#奇数和
    even_sum=0#偶数和
    for i in range(1,num+1):
        if i%2!=0:
            odd_sum+=i
        else:
            even_sum+=i
        s+=i
    return odd_sum,even_sum,s

res=get_sum(10)
print(type(res),res)#输出为元祖类型

#系列解包赋值
a,b,c = get_sum(10)
print(a)
print(b)
print(c)

3.变量的作用域

  • 指变量起作用的范围,根据作用的大小可分为局部变量和全局变量
    • 局部变量:
      • 在函数定义处的参数和函数内部定义的变量
      • 作用范围:仅仅在函数内部,函数执行结束,局部变量的生命周期也结束
    • 全局变量:
      • 在函数外定义的变量或函数内部使用global关键字修饰的变量
      • 作用范围:整个程序,程序运行结束,全局变量的生命周期才结束
  • 注意:
    • 当全局变量和局部变量名称相同时,局部变量优先级高
    • 使用global关键字声明后,这个变量就变成了全局变量;声明和赋值必须分开
python 复制代码
#局部变量
# def fun(a,b):
#     s=a+b
#     return s
# print(a,b,s)

#全局变量
d=3
def fun2(x,y):
    return x+y+d
print(d)
print(fun2(1,2))

print("-"*10)

def fun3(x,y):
    d=300 #局部变量,局部变量的名称和全局变量的名称相同
    return x+y+d #d 为全局变量还是局部变量? 局部变量
#当全局变量和局部变量名称相同时,局部变量优先级高
print(d)
print(fun3(1,2))

print("-"*30)

def fun4(x,y):
    global s #使用global关键字声明后,这个变量就变成了全局变量
    s = 300 #声明和赋值必须分开
    return x+y+s
print(fun4(1,3))
print(s)

4.匿名函数

  • 指没有名字的函数,这种函数只能使用一次,一般是在函数的函数体只有一句代码 且 只有一个返回值时,可以使用匿名函数来简化
  • 语法结构:result = lambda 参数列表:表达式
python 复制代码
def calc(a,b):
    return a+b
print(calc(1,2))

#简化
s=lambda a,b:a+b #s表示的就是一个匿名函数
print(type(s))

#调用
print(s(20,30))

#列表取值可以使用
lst =[1,2,3,4,5]
for i in range(len(lst)):
    print(lst[i])
print()

for i in range(len(lst)):
    res=lambda x:x[i] #根据索引取值 ,res类型是function, x是形式参数
    print(res(lst)) #lst是实际参数

# 排序
student_score=[
    {'name:':"一一",'score:':100},
    {'name':"二二",'score:':90},
    {'name:':"飒飒",'score:':100},
    {'name:':"思思",'score:':98},
    {'name:':"呜呜",'score:':99}
]
# 对列表进行排序,排序的规则,是字典的成绩
student_score.sort(key = lambda x:x.get('score:'),reverse=True)#降序
print(student_score)

5.递归函数

  • 在一个函数体内调用该函数本身
  • 一个完整的递归操作由两部分组成:递归调用和递归终止条件,一般可以使用if-else结构来判断递归的调用额和递归的终止
  • 占用内存比较多,每调用一次就建立一个栈帧
python 复制代码
def fac(n): # n的阶乘
    if n==1:
        return 1
    else:
        return n*fac(n-1) #自己调用自己

print(fac(5))
  • 斐波那契数列:指这样一个数列:1,1,2,3,5,8,13,21,34...,从第三项开始,每一项都等于前两项之和
    • 公式:f(n)= f(n-1)+f(n-2)
python 复制代码
def fac(n):
    if n==1 or n==2:
        return 1
    else:
        return fac(n-1)+fac(n-2)
print(fac(9))

for i in range(1,10):
    print(fac(i),end="\t")
print()

6.内置函数

  • 类型转换函数
python 复制代码
# 1.bool类型
print("非空字符串",bool("Hello"))# True ,其余都是False
print("空字符",bool(""))# 空字符串不是空格字符串
print("空列表的布尔值:",bool([]))
print("空列表的布尔值:",bool(list()))
print("空元组的布尔值:",bool(()))
print("空元组的布尔值:",bool(tuple()))
print("空字典的布尔值:",bool({}))
print("空字典的布尔值:",bool(dict()))
print("空集合的布尔值:",bool(set()))

print("-"*30)
print("非0数值型的布尔值:",bool(1)) #True
print("整数0的布尔值:",bool(0))
print("浮点数0.0的布尔值:",bool(0.0))

print("str-"*40)
 # 2.将其他类型转换成字符串类型 str
lst = [1,2,3]
print(type(lst),lst)
s = str(lst)
print(type(s),s)
print("-int类型"*40)
#3.float类型和str类型转换为int类型
print(int(12.3)+int("12"))
#注意.字符串里是浮点数就不可以转
# print(int("12.3"))#ValueError: invalid literal for int() with base 10: '12.3'
# print(int("a")) #ValueError: invalid literal for int() with base 10: 'a'

print("-float类型"*40)

# 4.转为float类型
print(float(11))
print("-.转列表"*40)
# 5.转列表
s = "hello"
print(list(s))
print("-元组"*40)
seq= range(1,10)
# 6.转元组
print(tuple(seq))
print("-添加到集合"*40)
#7.添加到集合
print(set(seq))
  • 数学函数
python 复制代码
# 1.绝对值
print("绝对值:",abs(100),abs(-100),abs(0))

# 2.商和余数
print("商,余数 : ",divmod(13,4))

# 3.最大值
print("最大值:",max("Hello"))
print("最大值:",max([1,2,4,642,1]))

# 4.最小值
print("最小值:",min('hello'))
print("最小值:",min([1,4,2,131,12]))

# 4.求和
print("求和:",sum([1,2,4,3,21,2]))

# 5.x的y次幂
print("x的y次幂,",pow(2,3))# 底数,指数

# 6.四舍五入
print("四舍五入:",round(1.1121312314345655)) #round函数只有一个参数,保留整数
print("四舍五入,保留两位小数:",round(1.323456765432,2)) # 小数,保留位数
print("四舍五入,保留数为负数:",round(13432.12313,-1)) # -1就是对小数个位的数进行四舍五入
print("四舍五入,保留数为负数:",round(13432.12313,-2)) # -2就是对小数十位的数进行四舍五入,以此类推
  • 迭代器操作函数
python 复制代码
lst=[12,32,25,29,15]
# 1.排序
asc_lst = sorted(lst)
desc_lst = sorted(lst,reverse=True)
print("原列表:",lst)
print("升序列表:",asc_lst)
print("降序列表:",desc_lst)

print("-"*10+"反向"+"-"*30)
# 2.reversed 反向
new_lst = reversed(lst)
print(type(new_lst)) # <class 'list_reverseiterator'> 迭代器对象
print(list(new_lst))

print("-"*10+"zip"+"-"*30)
# 3.zip
x= ["a","b","c","d","e"]
y=[1,2,3,4,5]
zipobj=zip(x,y)
# print(type(zipobj))#<class 'zip'>
# print(list(zipobj))

print("-"*10+"enumerate"+"-"*30)
# 4.enumerate
e = enumerate(y,start=3)
s = enumerate(y,8)
print(type(enumerate)) #<class 'type'>
print(tuple(e))
print(list(s))

print("-"*10+"all"+"-"*30)
#5.all
lst2=[12,32,45,""]
print(all(lst2)) # False ,空字符串的布尔值是False
print(all(lst)) # True

print("-"*10+"any"+"-"*30)
print(any(lst2)) # True ,只要有一个为True,就为True

print("-"*10+"next"+"-"*30)
print(next(zipobj)) # 每运行一次就会得到一个元素 ,上面输出太多,出现StopIteration错误,解决方法,异常操作
# try:
#     while True:
#         print(next(zipobj))  # 尝试获取下一个元素
# except StopIteration:
#     print("迭代器已耗尽")

# 6.filter
print("-"*10+"filter"+"-"*30)
def fun (num):
    return num %2==1 #True/False
# 函数当参数的时候不用写括号
obj=filter(fun,range(10)) #将range(10),0-9的整数,都执行一次fun操作
print(list(obj))

print("-"*10+"map"+"-"*30)
# 7.map
def upper(x):
    return x.upper()
new_lst2 = ["hello","java","python"]
obj2 = map(upper,new_lst2)
print(list(obj2))
  • 其他函数

7.练习题

  • 1.编写函数实现计算列表中元素的最大值
  • 随机产生10个元素,存储到列表中去,编写函数获取列表中元素的最大值(不能使用max())
python 复制代码
import random
def get_max(lst):
    x=lst[0] #假设x存储是元素的最大值
    # 遍历
    for i in range(1,len(lst)):
        if lst[i]>x:
            x=lst[i] #对最大值进行重新赋值
    return x
# 调用
lst=[random.randint(1,100) for item in range(10)]
print(lst)
#计算列表元素的最大值
max=get_max(lst)
print(max)
  • 2.编写函数实现提取指定字符串是数字并求和
  • 使用input()获取一个字符串,编写并传参,使用isdigit()方法提取字符串所有的数字,并对提取的数字进行求和运算,最后将存储数字的列表和累加和返回
python 复制代码
# s = input("请输入一个字符串")
def get_digit(x):
    s=0 #存储累加和
    lst=[] # 存储提取的数字
    for item in x:
        if item.isdigit(): #如果是数字
            lst.append(int(item))
    s= sum(lst) # 调用内置函数sum
    return lst,s
s = input("请输入一个字符串") # input()本身返回的就是字符串
lst,x=get_digit(s)# 调用函数
print("提取的数字:",lst)
print("数字之和:",x)
  • 3.编写函数实现将字符串中的字母大小写转换
  • 使用input()函数获取一个字符串,编写并传参,将字符串中所有小写字母转成大写字母,将大写字母转成小写字母
python 复制代码
def trans(x):
    lst=[] #存储转换后的字符
    #把字符串分割
    for i in x:
        # A 65 ;a 97
        if "A"<=i <= "Z":
            lst.append(chr(ord(i) +32))#将字符转换为对应的Unicode码 , 加 32判断是否在小写的范围内, chr将整数码转换为字符
        elif"a"<=i<="z":
            lst.append(chr(ord(i)-32))
        else:
            lst.append(i)
    return"".join(lst) #使用join()将列表的字符拼接成字符串返回
s=input("请输入一个字符串")
new_s=trans(s)
print(new_s)
  • 4.编写函数实现操作符in的功能
  • 使用input()函数从键盘获取一个字符串,判断这个字符串在列表中是否存在(函数体不能使用in),返回结果为True/False
python 复制代码
def get_find(s,lst):
    for i in lst:
        if s==i:
            return True
    return False
lst=["hello","world","python"]
s=input("请输入一个字符串")
res = get_find(s,lst)
print("存在" if res else "不存在")
相关推荐
_深海凉_14 分钟前
LeetCode热题100-颜色分类
python·算法·leetcode
AC赳赳老秦36 分钟前
OpenClaw email技能:批量发送邮件、自动回复,高效处理工作邮件
运维·人工智能·python·django·自动化·deepseek·openclaw
zhaoshuzhaoshu1 小时前
Python 语法之数据结构详细解析
python
AI问答工程师1 小时前
Meta Muse Spark 的"思维压缩"到底是什么?我用 Python 复现了核心思路(附代码)
人工智能·python
zfan5202 小时前
python对Excel数据处理(1)
python·excel·pandas
小饕2 小时前
我从零搭建 RAG 学到的 10 件事
python
老歌老听老掉牙2 小时前
PyQt5+Qt Designer实战:可视化设计智能参数配置界面,告别手动布局时代!
python·qt
无限进步_2 小时前
【C++】只出现一次的数字 II:位运算的三种解法深度解析
数据结构·c++·ide·windows·git·算法·leetcode
格鸰爱童话3 小时前
向AI学习项目技能(六)
java·人工智能·spring boot·python·学习
悟空爬虫-彪哥3 小时前
VRChat开发环境配置,零基础教程
python