函数
函数内容补充:https://blog.csdn.net/weixin_44134356/article/details/119189688?spm=1001.2014.3001.5501
1.认识函数
1)什么是函数(机器)
- 函数就是实现某一特定功能的代码的封装。
- 函数就是把实现某一个功能的所有的代码打成了一个包,每次需要这个功能的时候不用再重复去写实现这个功能的代码了,而是使用函数。
2)函数的分类
按函数是由谁创建/定义来进行分类:
- 系统函数
- 由系统定义提供的函数,这类函数只需要在需要它功能时调用即可(系统已造好的机器)
- 例如:print、input、len、id、max、min、type等…
- 由程序员自己创建使用的函数。(自己创造机器)
2.定义/创建函数(造机器)
"""
def 函数名(形参列表):
函数说明文档
函数体
"""
"""
def和冒号 - 固定写法
函数名 - 程序员自行命名,要求标识符且不是关键字,规范见名知意,字母小写多个单词下划线隔开,不使用系统用的名
() - 固定写法
形参列表 - 格式:变量,可接收传过来的实参值,多个变量逗号隔开。(可没有形参)
形参作用:将函数外部的数据传递到函数里面使用
函数说明文档 - 本质就是一个多行注释(机器的说明书)
函数体 - 功能的实现代码
"""
初学者定义函数的基本步骤:
- 确定函数的功能(确定机器造出来是干嘛的)
- 根据功能确定函数名(给机器取名)
- 确定形参;看实现功能要不要额外数据,要几个
- 实现函数功能
- 返回值
- 写说明文档
实例
"""
例1:定义一个函数将两个字符串合并成一个字符串,合并方式如下:
'abc' 和 '123' 合并为:'a1b2c3'
'abcdef' 和 '123' 合并为:'a1b2c3def'
'abc' 和 '12345' 合并为:'a1b2c345'
"""
def merge(str1, str2):
len1 = len(str1)
len2 = len(str2)
str3 = ''
length = min(len1, len2)
for i in range(length):
str3 += str1[i] + str2[i]
else:
str3 += str1[length:] + str2[length:]
return str3
# 例2:定义一个函数打印10的阶乘
def factorial(num1=10):
return math.factorial(num1)
3.调用函数
- 定义函数的时候不会执行函数体,调用后才会执行。
- 调用函数的时候,实参的个数由被调用的函数的形参决定。(用实参给形参赋值的过程叫传参)
- 函数调用过程(简易)
当代码执行到函数调用语句的时候,后面的执行过程如下:
第一步:回到函数定义的位置
第二步:传参(用实参给形参赋值)
第三步:执行函数体
第四步:确定返回值
第五步:返回函数调用位置获取返回值,接着往后执行
- 语法:函数名(实参列表)
- 说明:
- 函数名 - 需要调用的函数的函数名(这个函数名对应的函数必须时已经定义好的函数)
- () - 固定写法
- 实参列表 - 格式:多个数据逗号隔开
实参就是给形参赋值。(需要运算执行的数据)
# 调用上面的2个自定义函数
print(merge('abcdef', '123'))
print(factorial())
"""
输出结果:
a1b2c3def
3628800
"""
4.函数的参数
根据调用函数的时候实参提供方式的不同,将实参分为位置参数和关键字参数两种
1) 位置参数和关键字参数
1-1位置参数
- 直接提供实参对应的数据,让实参和形参在位置上一一对应
1-2关键字参数
- 以’形参1=实参1, 形参2=实参2,…’ 方式使用
1-3两者混合用
- 位置参数和关键字参数一起用,前提必须保证位置参数在前,关键字参数在后
实例
def func1(a, b, c):
print(f'a:{a},b:{b},c:{c}')
# 位置参数
func1(100, 200 ,300) # a:100,b:200,c:300
# 关键字参数
func1(b=200, a=100, c=300) # a:100,b:200,c:300
# 混用
func1(100, c=300, b=200) # a:100,b:200,c:300
2) 参数默认值
- 定义函数的时候可以以‘形参名=值’的形式给形参提供默认值;
- 如果一个参数有默认值,在调用时有默认值的参数可以不传参。
- 如果定义函数的时候有的参数有默认值,有的没有,那么没有默认值的参数必须写在前面
实例
def func1(a=10, b=20, c=30):
print(f'a:{a},b:{b},c:{c}')
# 有默认值可不传实参
func1() # a:10,b:20,c:30
func1(100) # a:100,b:20,c:30
func1(100, 200) # a:100,b:200,c:30
func1(100, 200, 300) # a:100,b:200,c:300
func1(b=200) # a:10,b:200,c:30 (跳过有默认值的参数,给后面的参数传参使用关键参数)
3) 参数类型说明
- 有默认值的参数:默认值是什么类型,类型说明就是什么类型
- 没有默认值的参数:需要在形参后加’:类型名’
def func2(x:list, y=''):
pass
4) 不定长参数
4-1 带*的不定长参数(保存为元组)
- 如果在一个形参前加*,那么这个形参就可以接受任意多个实参。
- 这个带*的形参会变成一个元组来保存接收实参,对应的实参是元组中的元素。
注意:带*的参数后面如果还有形参,后面的形参必须使用关键字参数赋值,否则会报错
4-2 带**的不定长参数(保存为字典)
- 调用时传参格式:‘形参=值’ - 相当于字典中的键值对
实例
# 带*的不定长参数
def func3(a, *b, c):
print(f'a:{a},b:{b},c:{c}') # a:1,b:(2, 3, 4),c:5
func3(1,2,3,4,c=5)
# 带**的不定长参数
def func4(a, **b):
print(f'a:{a},b:{b},类型:{type(b)}') # a:1,b:{'name': 'mick', 'age': 4},类型:<class 'dict'>
func4(1,name='mick',age=4)
# 实例:定义一个函数求多个数的和。
def func5(a, *nums, b):
print(f'a:{a},b:{b}, nums的类型:{type(nums)}') # a:2,b:5, nums的类型:<class 'tuple'>
print(f'其他数的和:{sum(nums)}') # 其他数的和:18
func5(2,5,3,10,b=5)
5.函数的返回值
1)返回值的作用
- 就是将函数内部产生的数据,传递到函数外部。
2)确定函数的返回值
- 在函数中通过return关键字返回函数的返回值: return 数据
注意:1)如果执行函数体的时候没有遇到返回值,函数返回值是None
2)return还具有提前结束函数的功能(相当于循环中的break)
3)怎么在函数外获取返回值
-
获取函数调用表达式的值就是获取函数的返回值
-
每一个函数调用语句其实都有一个结果(都是一个数据),这个结果就是这次调用的时候函数的返回值
def sum1():
return 10+20
sum2 = sum1() # 获取返回值,变量保存
print(sum2) # 30
课后练习
-
编写一个函数,交换指定字典的key和value。
例如:dict1={'a':1, 'b':2, 'c':3} --> dict1={1:'a', 2:'b', 3:'c'}
def exchange(dict1): dict2 = {dict1[key]:key for key in dict1} return dict2 dict1 = {'name': '旺仔', 'age': 8} print(exchange(dict1))
-
编写一个函数,提取指定字符串中所有的字母,然后拼接在一起产生一个新的字符串
例如: 传入'12a&bc12d-+' --> 'abcd'
def extract(str1): strs = '' for i in str1: if 'a' <= i <= 'z' or 'A' <= i <= 'Z': strs += i print(strs) str1 = '12a&bc12d-+' extract(str1)
-
写一个自己的capitalize函数,能够将指定字符串的首字母变成大写字母
例如: 'abc' -> 'Abc' '12asd' --> '12asd'
def capitalize1(str1): str2 ='' if 'a' <= str1[0] <= 'z': str2 += chr(ord(str1[0])-32) + str1[1:] return str2 return str1 str1 = capitalize1('abc') print(str1)
-
写一个自己的endswith函数,判断一个字符串是否已指定的字符串结束
例如: 字符串1:'abc231ab' 字符串2:'ab' 函数结果为: True 字符串1:'abc231ab' 字符串2:'ab1' 函数结果为: False
def endswith(str1, str2): len_str2 = len(str2) if str1[-len_str2:] == str2: return True return False str1 = '123456' print(endswith(str1, '56'))
-
写一个自己的isdigit函数,判断一个字符串是否是纯数字字符串
例如: '1234921' 结果: True '23函数' 结果: False 'a2390' 结果: False
def isdigit1(str1): if not str1: return False for i in str1: if '0' > i or i > '9': return False return True print(isdigit1('123'))
-
写一个自己的upper函数,将一个字符串中所有的小写字母变成大写字母
例如: 'abH23好rp1' 结果: 'ABH23好RP1'
def upper1(str1): str2 = '' for i in str1: if 'a' <= i <= 'z': str2 += chr(ord(i) - 32) continue str2 += i return str2 print(upper1('abH23好rp1'))
-
写一个自己的rjust函数,创建一个字符串的长度是指定长度,原字符串在新字符串中右对齐,剩下的部分用指定的字符填充
例如: 原字符:'abc' 宽度: 7 字符:'^' 结果: '^^^^abc' 原字符:'你好吗' 宽度: 5 字符:'0' 结果: '00你好吗'
def rjust1(str1, width, char): len_str1 = len(str1) if len_str1 >= width: return str1 str2 = char*(width-len_str1) + str1 return str2 print(rjust1('123', 3, '@'))
-
写一个自己的index函数,统计指定列表中指定元素的所有下标,如果列表中没有指定元素返回-1
例如: 列表: [1, 2, 45, 'abc', 1, '你好', 1, 0] 元素: 1 结果: 0,4,6 列表: ['赵云', '郭嘉', '诸葛亮', '曹操', '赵云', '孙权'] 元素: '赵云' 结果: 0,4 列表: ['赵云', '郭嘉', '诸葛亮', '曹操', '赵云', '孙权'] 元素: '关羽' 结果: -1
def index1(lists:list, item:str): indexs = [] for i in range(len(lists)): if item == lists[i]: indexs.append(i) if len(indexs): return indexs return -1 print(index1(['赵云', '郭嘉', '诸葛亮', '曹操', '赵云', '孙权'], '关羽'))
-
写一个自己的len函数,统计指定序列中元素的个数
例如: 序列:[1, 3, 5, 6] 结果: 4 序列:(1, 34, 'a', 45, 'bbb') 结果: 5 序列:'hello w' 结果: 7
def len1(order): count = 0 for i in order: count += 1 return count print(len1('hello w'))
-
写一个自己的max函数,获取指定序列中元素的最大值。如果序列是字典,取字典值的最大值
例如: 序列:[-7, -12, -1, -9] 结果: -1 序列:'abcdpzasdz' 结果: 'z' 序列:{'小明':90, '张三': 76, '路飞':30, '小花': 98} 结果: 98
def max1(order): if type(order) == set: order = list(order) if type(order) == dict: order = list(order.values()) max2 = order[0] for i in order: if max2 < i: max2 = i return max2 print(max1('abcdpzasdz'))
-
写一个函数实现自己in操作,判断指定序列中,指定的元素是否存在
例如: 序列: (12, 90, 'abc') 元素: '90' 结果: False 序列: [12, 90, 'abc'] 元素: 90 结果: True
def in1(order, item): for i in order: if item == i: return True else: return False print(in1([12, 90, 'abc'], 90))
-
写一个自己的replace函数,将指定字符串中指定的旧字符串转换成指定的新字符串
例如: 原字符串: 'how are you? and you?' 旧字符串: 'you' 新字符串:'me' 结果: 'how are me? and me?'
def replace1(strs, str1, str2): len_str1 = len(str1) str3 = '' index = 0 while index < len(strs): if strs[index:index+len_str1] == str1: str3 += str2 index += len_str1 continue str3 += strs[index] index += 1 return str3 print(replace1('how are you? and you?', 'you', 'me')) def replace2(strs: str, old_str: str, new_str: str): return new_str.join(strs.split(old_str)) print(replace2('how are you? and you?', 'you', 'me'))