函数基础
函数
函数定义
-
函数就是实现某一特定功能的代码的封装;(每个函数都有自己特定的功能)
-
函数就是把实现某一个功能的所有代码打成一个包,每次需要这个功能的时候不用重复写实现这个功能的代码,而是使用函数。
函数的分类
- 按照函数是由谁创建/定义来进行的分类;
- 系统函数 - 由python定义的函数,这类函数的使用只需要直接调用就行;
- 自定义函数 - 由程序员自己创建自己使用的函数;
定义(创建)函数
语法
def 函数名(形参列表):
函数说明文档
函数体
说明
- def | : | () - 固定写法
- 函数名
- 程序员自己命名;(是标示符,不是关键字,见名知义);
- 单词间用下划线隔开,不适用系统的函数名,类名;
- 形参列表 - 格式:使用多个变量名用逗号隔开,每个变量表示一个形参(可以没有形参);
- 形参作用:将函数外部的数据传递到函数里面;
- 函数说明文档 - 本质就是多行注释,对函数进行功能说明;
- 函数体
- 和def保持一个缩进的一条或者多条语句;
- 实现这个函数功能的代码;
初学者定义函数步骤
- 确定函数的功能
- 根据功能确定函数名
- 确定函数参数(确定形参),实现函数的功能是否需要额外的数据,需要几个;
- 利用形参提供的数据通过函数体实现函数功能
- 确定返回值
- 说明文档的编写
# 练习1:定义一个函数求两个数的和
def sum1(x, y):
sum_1 = x + y
return sum_1
# 练习2:定义一个函数获取指定整数的个位数
def get_ones_place(int1):
return int1 % 10
# 练习3:定义一个函数获取指定字符串中数字字符的个数
def get_numbers_num(in_str):
count = 0
for item in in_str:
if '0' <= item <= '9':
count += 1
return count
# 练习4:定义一个函数将两个字符串合并成一个字符串,合并方式如下:
# 'abc' 和 '123' 合并为:'a1b2c3'
# 'abcdef' 和 '123' 合并为:'a1b2c3def'
# 'abc' 和 '12345' 合并为:'a1b2c345'
def merge_str(in_str1, in_str2):
"""
混合两个字符串,'abcdef' 和 '123' 合并为:'a1b2c3def'
:param in_str1: 字符串1
:param in_str2: 字符串2
:return: 合并后的新字符串
"""
len1, len2 = len(in_str1), len(in_str2)
new_str = ''
length = min(len1, len2)
for index1 in range(length):
new_str += (in_str1[index1] + in_str2[index1])
new_str += in_str1[length:] + in_str2[length:]
return new_str
print(merge_str('abcdef', '123'))
# 练习5:定义一个函数打印10的阶乘
def factorial_10():
factorial1 = 1
for i in range(1, 10 + 1):
factorial1 *= i
return factorial1
print(factorial_10())
调用函数
-
定义函数不会执行函数,调用函数才会执行函数体。(调用多少次,函数体就会执行多少次);
-
调用函数的时候,实参的个数由被调用的函数的形参决定。(实参给形参赋值的过程叫传参);
-
语法:函数名(实参列表)
-
说明
- 函数名 - 需要调用的函数的函数名(这个函数名对应的函数必须是已经定义好的函数)
- () - 固定写法
- 实参列表
- 格式:多个数据用逗号隔开实参是用来给形参赋值;
- 实参就是通过形参传递到函数内部的数据;
函数调用过程
- 回到函数定义的位置;
- 传参,用实参给形参赋值;
- 执行函数体;
- 确定返回值;
- 返回函数调用的位置,继续执行代码;
函数的参数
根据实参提供方式分类
- 位置参数
- 关键字参数
- 以’形参1=实参1,形参2=实参2,…'的形式传参;
- 位置参数与关键字参数混用
- 位置参数和关键字参数可以一起使用,混用时必须保证位置参数在关键字参数前面
def func1(a, b, c):
print(f'a:{a},b:{b},c:{c}')
func1(10, b=20, c=30) # a:10,b:20,c:30
func1(10, c=30, b=20) # a:10,b:20,c:30
func1(10, 20, c=30) # a:10,b:20,c:30
参数默认值
- 定义函数的时候可以以**‘形参名=值’**的形式给形参提供默认值;
- 如果一个参数有默认值,那么在调用函数的时候有默认值的参数可以不用传参;
- 如果需要跳过前面的参数默认值,只能使用后面参数的关键字传参;
- 如果定义函数时部分形参有参数默认值,那么没有默认值的参数必须放在有默认值参数的前面;
def func2(a=10, b=20, c=30):
print(f'a:{a},b:{b},c:{c}')
func2() # a:10,b:20,c:30
func2(100) # a:100,b:20,c:30
func2(c=300) # a:10,b:20,c:300
参数类型说明
-
有默认值的参数,默认值是什么类型,类型说明就直接是什么类型
-
没有默认值的参数,需要要在形参后加’:类型名’
不定长参数
带*的不定长参数
- 如果在一个形参前加*,那么这个形参(变为元组)就能接受任意多个实参;
- 带*的不定长参数本质就是一个元组,对应的多个实参是元组中的元素;
- 注意:带*的不定长参数只能用位置参数,不能使用关键字参数;
- 如果定长参数在带*参数(有时直接在*后面)后面,那么后面的定长参数调用的时候必须用关键字参数传参;
带**的不定长参数
def n_sum(*args):
sum1 = 0
for i in args:
sum1 += i
return sum1
print(n_sum(20, 30, 4)) # 54
def func7(*a, b, c):
print(f'a:{a},b:{b},c:{c}')
func7(10, 20, 30, 40, b=50, c=60) # a:(10, 20, 30, 40),b:50,c:60
def func9(**x):
pass
func9(a=10, b=20, c=30)
函数返回值
返回值作用
-
返回值的作用就是将函数内部产生的数据,传递到函数外部;
-
是否需要返回值:看函数的功能有没有产生新的数据,如果有就将新的数据作为返回值返回;
确定函数的返回值
-
renturn 数据 - 在函数体中通过return 关键字返回函数的返回值
-
函数调用表达式 - 调用函数的语句
- 每一个函数调用语句其实都有一个结果(都是一个数据),这个结果就是这次调用时函数的返回值
- 一个函数的返回值是什么,就看调用函数的时候return后面的值是什么,函数外部函数调用表达式的结果就是什么。
-
注意
- 如果执行函数体的时候没有遇到return,函数的返回值是None
- return还具有提前结束函数的功能(执行函数体的时候在哪遇到return,函数就在哪结束)
def sum2(num1, num2):
s = num1 + num2
return s
print(sum2(78, 90))
def func1():
return 100
a = func1()
print(a)
print('----------------------------------------')
# 没有遇到return,返回值是None
def func3():
print('abc')
result = func3()
print('返回值:', result) # 返回值: None
def func4(x):
if x % 2:
return 100
print('返回值:', func4(20)) # 返回值: None
print('返回值:', func4(21)) # 返回值: 100
def func5():
for x in range(100):
return x
print(func5()) # 0
作业
-
编写一个函数,交换指定字典的key和value。
例如:dict1={'a':1, 'b':2, 'c':3} --> dict1={1:'a', 2:'b', 3:'c'}
def exchange_key_value(in_dict): return {in_dict[key]: key for key in in_dict} print(exchange_key_value({'a':1, 'b':2, 'c':3}))
-
编写一个函数,提取指定字符串中所有的字母,然后拼接在一起产生一个新的字符串
例如: 传入'12a&bc12d-+' --> 'abcd'
def extract_letters(in_str: str): return ''.join([item for item in in_str if 'a' <= item <= 'z' or 'A' <= item <= 'Z']) print(extract_letters('12a&bc12d-+'))
-
写一个自己的capitalize函数,能够将指定字符串的首字母变成大写字母
例如: 'abc' -> 'Abc' '12asd' --> '12asd'
def capitalize4(in_str): if 'a' <= in_str[0] <= 'z': new_str = chr(ord(in_str[0]) - 32) + in_str[1:] else: new_str = in_str return new_str print(capitalize4('12abc'))
-
写一个自己的endswith函数,判断一个字符串是否已指定的字符串结束
例如: 字符串1:'abc231ab' 字符串2:'ab' 函数结果为: True 字符串1:'abc231ab' 字符串2:'ab1' 函数结果为: False
def endswith4(in_str, find_str): len1 = len(in_str) - len(find_str) new_list = [in_str[:len1], in_str[len1:]] if find_str in new_list: return True else: return False print(endswith4('12345', '45'))
-
写一个自己的isdigit函数,判断一个字符串是否是纯数字字符串
例如: '1234921' 结果: True '23函数' 结果: False 'a2390' 结果: False
def isdigit(in_str): if not len(in_str): return False else: for item in in_str: if not '0' <= item <= '9': return False else: return True print(isdigit('23函数'))
-
写一个自己的upper函数,将一个字符串中所有的小写字母变成大写字母
例如: 'abH23好rp1' 结果: 'ABH23好RP1'
def upper1(in_str): return ''.join([chr(ord(item) - 32) if 'a' <= item <= 'z' else item for item in in_str]) print(upper1('abH23好rp1'))
-
写一个自己的rjust函数,创建一个字符串的长度是指定长度,原字符串在新字符串中右对齐,剩下的部分用指定的字符填充
例如: 原字符:'abc' 宽度: 7 字符:'^' 结果: '^^^^abc' 原字符:'你好吗' 宽度: 5 字符:'0' 结果: '00你好吗'
def rjust1(in_str: str, length: int, assign_str: str): len1 = len(in_str) if len1 >= length: return in_str else: return assign_str * (length - len1) + in_str print(rjust1('abc',7,'^'))
-
写一个自己的index函数,统计指定列表中指定元素的所有下标,如果列表中没有指定元素返回-1
例如: 列表: [1, 2, 45, 'abc', 1, '你好', 1, 0] 元素: 1 结果: 0,4,6 列表: ['赵云', '郭嘉', '诸葛亮', '曹操', '赵云', '孙权'] 元素: '赵云' 结果: 0,4 列表: ['赵云', '郭嘉', '诸葛亮', '曹操', '赵云', '孙权'] 元素: '关羽' 结果: -1
def index1(in_list, assign_item): count = [] for index1, item in enumerate(in_list): if item == assign_item: count.append(index1) if not len(count): return -1 else: return count print(index1([1, 2, 45, 'abc', 1, '你好', 1, 0],1))
-
写一个自己的len函数,统计指定序列中元素的个数
例如: 序列:[1, 3, 5, 6] 结果: 4 序列:(1, 34, 'a', 45, 'bbb') 结果: 5 序列:'hello w' 结果: 7
def len1(sequence): count = 0 for _ in sequence: count += 1 return count print(len1((1, 34, 'a', 45, 'bbb')))
-
写一个自己的max函数,获取指定序列中元素的最大值。如果序列是字典,取字典值的最大值
例如: 序列:[-7, -12, -1, -9] 结果: -1 序列:'abcdpzasdz' 结果: 'z' 序列:{'小明':90, '张三': 76, '路飞':30, '小花': 98} 结果: 98
def max1(sequence): if type(sequence) == dict: max_value = sequence.popitem()[1] for _, value in sequence.items(): if value > max_value: max_value = value return max_value else: max_value = sequence[0] for item in sequence[1:]: if item > max_value: max_value = item return max_value print(max1({'小明': 90, '张三': 76, '路飞': 30, '小花': 98}))
-
写一个函数实现自己in操作,判断指定序列中,指定的元素是否存在
例如: 序列: (12, 90, 'abc') 元素: '90' 结果: False 序列: [12, 90, 'abc'] 元素: 90 结果: True
def in1(sequence, assign_item): for item in sequence: if item == assign_item: 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(in_str:str,old_str:str,new_str:str): if old_str in in_str: return new_str.join(in_str.split(old_str)) else: return -1 print(replace1('how are you? and you?','you','me'))