1. 函数的概念
函数就是实现某一特定功能的代码的封装。 - 不同的函数有不一样的功能
def sumx(N):
sum1 = 0
for x in range(1, N+1):
sum1 += x
print(sum1)
sumx(100)
sumx(50)
2. 函数的分类
根据函数是由谁定义的(创建的)将函数分为:系统函数、自定义函数
1)系统函数 - 系统自带的函数(创建Python语言的人创建好的函数) (别人造好的机器),例如:max、min、sum、print、type、input、…
2)自定义函数 - 由程序员自己创建的函数 (自己造的机器)
3. 定义函数(创建函数) - 造机器
语法:
def 函数名(形参列表):
函数说明文档
函数体
说明:
def - 关键字;固定写法
函数名 - 由程序员自己命名;
要求:标识符、不是关键字
规范:见名知义(看到函数名大概知道函数的功能)、所有字母都小写,多个单词之间用下划线隔开、
不使用系统的函数名、类名和模块名
(): - 固定写法
形参列表 - 以 ‘变量名1, 变量名2, 变量名3,…’ 的形式存在,这儿的一个变量代表一个形参(也可以一个形参都没有);
形参可以将函数外部的数据传递到函数里面。
定义函数的时候需不需要形参就看实现函数的功能需不需要额外的数据。
函数说明文档 - 本质就是多行注释(相当于机器的说明书)
函数体 - 和def保持一个缩进的一条或者多条语句;
函数体就是实现函数功能的代码。
4.初学者定义函数的基本步骤
第一步:确定函数功能
第二步:根据函数功能确定函数名字
第三步:确定参数(看实现函数的功能需不需要额外的数据,需要几个?)
第四步:实现函数功能(将形参当成数据来使用)
第五步:写函数说明文档
# 练习1: 定义一个函数统计字符串中中文的个数
def count_chinese(str1):
"""统计字符串中中文的个数"""
count = 0
for x in str1:
if '\u4e00' <= x <= '\u9fa5':
count += 1
print(f'中文个数:{count}')
count_chinese('wfuj萨芬nhg地方ch')
# 练习2:写一个函数,提取列表中所有的数字元素
def get_nums(list1):
"""提取列表中所有的数字元素"""
result = [x for x in list1 if type(x) in (int, float)]
print(result)
# 练习3:写一个函数,获取指定字典中所有的值
def get_values(dic):
"""获取指定字典中所有的值"""
result = [dic[key] for key in dic]
print(result)
# 练习4:写一个函数统计一个字符串中另外一个字符串出现的次数
# 'mnabc123abc-293abcp' 'abc'
def count_str(str1, str2):
l2 = len(str2)
count = 0
for i in range(0, len(str1)):
if str1[i: i + l2] == str2:
count += 1
i += l2
print(count)
# 练习5:写一个函数将两个列表合并成一个字典(第一个列表的元素是键,第二个列表的元素是值)
def create_dict(list_key, list_value):
"""
将两个列表合并成一个字典。
注意:两个列表的长度必须一致,第一个列表的元素必须是不可变的数据
:param list_key: 提供键
:param list_value: 提供值
:return: None
"""
length = len(list_key)
result = {list_key[index]: list_value[index] for index in range(length)}
print(result)
1.调用函数 - 使用机器
语法:
函数名(实参列表)
说明:
函数名 - 需要调用的函数的函数名(必须是已经定义过的函数的函数名)
() - 固定写法
实参列表 - 以 ‘数据1, 数据2, 数据3,…’ 的形式存在
实参是用来给形参赋值,实参是真正从函数外部传递到函数内部的数据
注意:同一个函数可以在需要它的功能的是反复调用
2.函数调用过程
1)定义函数不会执行函数体,调用函数的时候才会执行函数体
2)执行过程
第一步:回到函数定义的位置
第二步:传参(用实参给形参赋值)
第三步:执行函数体
第四步:确定函数返回值
第五步:回到函数调用的位置,接着往后执行
1. 位置参数和关键字参数 - 实参
1)位置参数
以 ‘数据1, 数据2, 数据3,…’ 的形式存在,让实参和形参从位置上一一对应
(第一个实参给第一个形参赋值,第二实参给第二个形参赋值,…)
2)关键字参数
以 '形参1=实参1, 形参2=实参2,…'的形式存在
3)混用
如果位置参数和关键字参数一起用,那么位置参数必须在关键字参数的前面
def func1(x, y, z):
print(f'x:{x}, y:{y}, z:{z}')
# 位置参数
func1(10, 20, 30)
func1(20, 10, 30)
# 关键字参数
func1(x=100, y=200, z=300)
func1(y=200, z=300, x=100)
# 位置参数和关键字参数一起用
func1(10, y=20, z=30)
func1(10, z=30, y=20)
func1(10, 20, z=30)
# func1(x=10, 20, z=30) # SyntaxError: positional argument follows keyword argument
2. 参数默认值 - 形参
定义函数的时候可以用 ‘形参=值’ 的方式给参数赋默认值;
调用函数的时候有默认值的参数可以不用传参。
如果定义函数的时候有的参数有默认值,有的参数没有默认值,没有默认值的参数必须在有默认值参数的前面
def func2(x=10, y=20, z=30):
"""func2"""
print(f'x:{x}, y:{y}, z:{z}')
func2(100, 200)
func2(100, 200, 300)
func2(y=200)
func2(z=300)
def func3(x, y=20, z=30):
print(f'x:{x}, y:{y}, z:{z}')
# def func4(x=10, y=20, z): # SyntaxError: non-default argument follows default argument
# print(f'x:{x}, y:{y}, z:{z}')
# def func4(x=10, y, z): # SyntaxError: non-default argument follows default argument
# print(f'x:{x}, y:{y}, z:{z}')
3. 参数类型说明 - 形参
情况1:没有默认值的参数,在参数后加 ‘:类型名’
情况2:有默认值的参数,值的类型就是参数的说明类型
def func5(str1: str, list1=[]):
pass
4. *不定长参数 (了解) - 形参
1)带的不定长参数
在定义函数的时候可以在某个参数前加,那么这个带的参数就是一个不定长参数,可以同时接收多个实参。
带的参数会自动变成一个元组,接收到实参是元组中的元素。
调用的时候带*的不定长参数必须用位置参数传参
2)带**的不定长参数(了解)
def func6(*x):
print(x)
func6()
func6(10)
func6(10, 20)
func6(10, 20, 30, 40, 50)
定长在不定长前面,都使用位置参数
def func7(x, *y):
print(f'x:{x}, y:{y}')
func7(10, 20, 30, 40)
定长在不定长后面,定长必须使用关键字参数
def func7(*x, y):
print(f'x:{x}, y:{y}')
func7(10, 20, 30, 40, y=50)
# 这儿*的作用只是强迫调用func8的时候,b和c必须使用关键字参数传参
def func8(a, *, b, c):
pass
保证func10调用的时候足够灵活
def func10(*args, **kwargs):
pass
func10()
func10(10, 20)
func10(a=10, b=23)
func10(10, 20, x=10, y=23)
1. 返回值
1)返回值的意义
返回值就是从函数内部传递到函数外部的数据
2)怎么确定函数返回值
返回值就是return关键字后面的表达式值(执行函数体的是如果遇到return,return后面是什么,函数返回值就是什么)
如果没有遇到return,返回值None
3)怎么在函数外部使用函数返回值
函数调用表达式的值就是函数的返回值,所以返回值能做的事情,函数调用表达式都可以做
函数调用表达式 - 调用函数的语句
def func1():
print('abc')
return 100
result = 100
result = func1() # 100
print(f'result: {result}')
print(100, func1())
print(100 * 2, func1()*2)
list1 = [100, func1(), 200]
print(list1)
def func2(x: str):
# x = 'abc'
return x*2 # return 'abc'*2 -> return 'abcabc'
func2('abc') # 'abcabc'
print(func2('abc')[-1]) # 'abcabc'[-1] -> 'c'
# print('abcabc'[-1])
def func3():
return [10, 20]
result = func3() # result = [10, 20]
result.append(100)
print(result)
2.return的作用
作用1:确定函数返回值
作用2:提前结束函数 - 如果执行函数体的时候遇到return,函数直接结束
def func4(num):
print('+++')
if num == 0:
return 0
print('----')
print('====')
return 100
result = func4(0)
print(result)
作业
-
写一个函数,实现maketrans的功能,将两个字符串转换成一个字典,第一个字符串中的字符是键,第二个字符串中的字符是值
第一个字符串: ‘abcmn’ 第二个字符串:‘一二三四五’
结果:{‘a’: ‘一’, ‘b’: ‘二’, ‘c’: ‘三’, ‘m’: ‘四’, ‘n’: ‘五’}
def new_dict(str1_key, str2_value):
return {str1_key[i]: str2_value[i] for i in range(len(str1_key))}
print(new_dict('abcmn', '一二三四五'))
-
写一个属于自己的join函数,可以将任意序列中的元素以指定的字符串连接成一个新的字符串
序列: [10, 20, 30, ‘abc’] 字符串: ‘+’ 结果:‘10+20+30+abc’
序列: ‘abc’ 字符串: ‘–’ 结果:‘a–b--c’
注意:序列中的元素可以不是字符串哟
def new_str(list1, str2):
str1 = ''
for i in range(len(list1) - 1):
str1 += str(list1[i])
str1 += str2
return str1 + list1[-1]
print(new_str([10, 20, 30, 'abc'], '+'))
-
写一个输入自己的upper函数,判断指定字符串是否是纯大写字母字符串
‘AMNDS’ -> True
‘amsKS’ -> False
‘123asd’ -> False
def upper(str1: str):
for x in str1:
if not 'A' <= x <= 'Z':
return 'False'
return 'True'
-
写一个clear函数,清空指定列表。
注意:功能是将原列表清空,不产生新的列表
def clear_list(list1: list):
list1.clear()
return list1
-
写一个reverse函数,将列表中的元素逆序
两种方法:1.产生一个新的列表 2.不产生新的列表,直接修改原列表元素的顺序
# 方法一
def reverse_list(list1):
list2 = []
for i in range(-1, -len(list1) - 1, -1):
list2.append(list1[i])
return list2
# 方法二
def reverse_list(list1):
l = len(list1)
for i in range(int(l / 2)):
list1[i], list1[l - 1 - i] = list1[l - 1 - i], list1[i]
return list1
-
写一个replace函数,将字符串中指定的子串替换成新的子串
原字符串: ‘abc123abc哈哈哈uui123’ 旧子串: ‘123’ 新子串: ‘AB’
结果: ‘abcABabc哈哈哈uuiAB’
# 方法一
def new_str(str1, str2, str3):
l2 = len(str2)
str4 = ''
i = 0
while i < len(str1):
if str1[i:i + l2] == str2:
str4 += str3
i += l2
else:
str4 += str1[i]
i += 1
return str4
# 方法二
def replace_str(str1: str, old_str2, new_str3: str):
return new_str3.join(str1.split(old_str2))
-
写一个函数,可以获取任意整数的十位数
123 -> 2
82339 -> 3
9 -> 0
-234 -> 3
def get_decile(x: int):
x = abs(x) % 100 // 10
return x
-
写一个函数实现数学集合运算符 & 的功能,求两个集合的公共部分:
集合1: {1, 2, 3} 集合2: {6, 7, 3, 9, 1}
结果:{1, 3}
def set_intersection(set1, set2):
return set1 & set2
-
写一个函数实现属于自己的字典update方法的功能,将一个字典中的键值对全部添加到另外一个字典中
字典1: {‘a’: 10, ‘b’: 20} 字典2: {‘name’: ‘张三’, ‘age’: 18} -> 结果让字典1变成: {‘a’: 10, ‘b’: 20, name’: ‘张三’, ‘age’: 18}
字典1: {‘a’: 10, ‘b’: 20} 字典2:{‘a’: 100, ‘c’: 200} -> 结果让字典1变成: {‘a’: 10, ‘b’: 20, ‘c’: 200}
def update(dict1, dict2):
for key in dict2:
dict1.setdefault(key, dict2[key])
return dict1
-
写一个函数判断指定数是否是回文数
12321 -> True
2332 -> True
9876789 -> True
1232 -> False
def palindromic_number(x: int):
length = len(str(x))
for i in range(length // 2):
if str(x)[i] != str(x)[length - i - 1]:
return 'False'
return 'True'
-
写一个函数判断指定数是否是完数(比较难)
完数:各个真因数的和等于这个数本身
例如:6是完数,6的真因子为1、2、3,1+2+3等于6,所以6是完数
28是完数,28的真因子:1、2、4、7、14,1+2+4+7+14等于28,所以28是完数
12不是完数:12的真因子:1、2、3、4、6,1+2+3+4+6不等于12
def judge_perfect_number(n: int):
sum1 = 1
for i in range(2, n // 2 + 1):
if n % i == 0:
sum1 += i
if sum1 == n:
return '%d是完美数' % n
return '%d不是完美数' % n