一、函数的初始
比如python没有len()方法,如何求字符串的长度
使用for循环
s = 'fdshfeigjoglfkldsja' count = 0 for i in s: count += 1 print(count)
执行输出:
19
列表呢?
li = [1,2,3,'a','b','c','ask'] count = 0 for i in li: count += 1 print(count)
执行输出:
7
如果是字典呢?
再把上面的代码贴一遍?
以上可以看出2点
1.重复代码多
2.可读性差
写代码,一切以精简为主,避免重复代码。
针对这种情况,出现了函数
函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。
函数的产生:
函数就是封装一个功能的代码片段。
def my_len(): #def 关键字 定义一个函数 #my_len 函数名的书写规则与变量一样。 #def 与函数名中间一个空格 #函数名(): 加上冒号(将函数名与函数体隔开),括号是用来传参的。 #函数体 就是函数里面的逻辑代码 count = 0 for j in li: count += 1 print(count)
以上就是一个函数
代码是从上至下执行的,执行到def my_len() 时
将my_len这个变量名加载到临时内存中,它不执行。
函数如何执行呢?
函数的执行:函数名 + ()
#执行函数 my_len()
当见到my_len()时,只有见到这个括号(),程序会根据函数名从内存中找到函数体,然后执行它
没有括号,它是不会执行的。
二、函数返回值
写函数,不要在函数中写print()
函数是以功能为导向的,除非测试的时候,才可以写print()
1.在函数中,遇到return结束函数。
def fun(): print(111) return print(444) fun()
执行输出:
111
2.将值返回给函数的调用者。
def fun(): a = 134 return a print(fun())
执行输出:
123
1.无 return
def fun(): pass print(fun())
执行输出:
None
2.return None (没有意义)
def fun(): return None print(fun())
执行输出:
None
3.return 1个值 该值是什么,就直接返回给函数的调用者,函数名()
def fun(): return [1,2,3] print(fun())
执行输出:
[1, 2, 3]
4.return 多个值 将多个值放到一个元组里,返回给函数的调用者。
def fun(): return 1,2,[33,44],'abc' print(fun())
执行输出:
(1, 2, [33, 44], 'abc')
li = [1,2,3,'a','b','c','ask'] def my_len(): count = 0 for j in li: count += 1 return count print(my_len())
执行输出:
7
查看len方法的源码
def len(*args, **kwargs): # real signature unknown """ Return the number of items in a container. """ pass
pass表示使用C写的
发现my_len()和len()方法,有些类似了。能返回变量的长度了,但是和len()有些区别。len可以传参数,比如len('123')
三、函数的传参
def my_len(l): # l 形式参数,形参 print(l) #实际对应就是a count = 0 for j in l: count += 1 return count a = 'fdsaf' print(my_len(a)) #括号里面的是实际参数,实参
执行输出:
fdsaf
5
实参角度:
1.位置传参。按顺序,一一对应。
def func(a,b,c): print(a) print(b) print(c) func('fdsafdas',3,4)
执行输出:
fdsafdas
3
4
如果少一个参数呢?
def func(a,b,c): print(a) print(b) print(c) func(3,4)
执行报错
TypeError: func() missing 1 required positional argument: 'c'
必须是一一对应的。
2.关键字传参,不按顺序,一一对应。
def max_min(a,b): return a if a > b else b print(max_min(b = 1,a = 3))
执行输出:
3
3.混合传参,关键字参数永远在最后面。
def func1(a,b,c,d,e): print(a) print(b) print(c) print(d) print(e) func1(1,2,c=3,4,5)
执行报错:
SyntaxError: positional argument follows keyword argument
正确的写法
def func1(a,b,c,d,e): print(a) print(b) print(c) print(d) print(e) func1(1,4,d=2,c=3,e=5)
执行输出:
1
4
3
2
5
按照形参角度:
1.位置传参。按顺序,一一对应。
def func(a,b,c): print(a) print(b) print(c) func('fdsafdas',3,4)
执行输出:
fdsafdas
3
4
2.默认参数。传参则覆盖,不传则默认,默认参数永远在位置参数后面
def func(a,b=666): print(a,b) func(1,2)
执行输出:
1 2
def func(a,b=666): print(a,b) func(1)
执行输出:
1 666
举一个场景
班主任录入员工信息表
while True: username = input('请输入姓名: ').strip() sex = input('请输入性别: ').strip() with open('name_list',encoding='utf-8',mode='a') as f1: f1.write('{} {} '.format(username,sex))
执行输出:
强制结束程序
查看文件内容
有2个问题
第一,男生居多
第二,完成函数功能
修改一下
def Infor_entry(username,sex='男'): with open('name_list',encoding='utf-8',mode='a') as f1: f1.write('{} {} '.format(username,sex)) while True: username = input('请输入姓名(男生以1开头):').strip() if '1' in username: #去除1 username = username[1:] Infor_entry(username) else: Infor_entry(username,'女')
执行输出:
查看文件
四、三元运算
三元运算符就是在赋值变量的时候,可以直接加判断,然后赋值
格式:[on_true] if [expression] else [on_false]
res = 值1 if 条件 else 值2
三元运算只适用于简单的if else判断,再多一层if判断就不适用了。
举例说明:
a =1 b = 2 c= a if a>1 else b #如果a大于1的话,c=a,否则c=b
写一个函数,功能比大小,大者返回
def max_min(a,b): if int(a) > int(b): return a else: return b print(max_min(1,3))
执行输出:
3
上面的max_min函数,可以使用三元运算进行简写
def max_min(a,b): z = a if a > b else b return z
再进一步简写
def max_min(a,b): return a if a > b else b
今日作业:
练习题 1、整理函数相关知识点,写博客 2、写函数,检查获取传入列表或元组对象的所有奇数位索引对应的元素,并将其作为新列表返回给调用者。 3、写函数,判断用户传入的对象(字符串、列表、元组)长度是否大于5。 4、写函数,检查传入列表的长度,如果大于2,那么仅保留前两个长度的内容,并将新内容返回给调用者。 5、写函数,计算传入字符串中【数字】、【字母】、【空格] 以及 【其他】的个数,并返回结果。 6、写函数,检查用户传入的对象(字符串、列表、元组)的每一个元素是否含有空内容,并返回结果。 7、写函数,检查传入字典的每一个value的长度,如果大于2,那么仅保留前两个长度的内容,并将新内容返回给调用者。 dic = {"k1": "v1v1", "k2": [11,22,33,44]} PS:字典中的value只能是字符串或列表 8、写函数,接收两个数字参数,返回比较大的那个数字。 9、写函数,用户传入修改的文件名,与要修改的内容,执行函数,完成整个文件的批量修改操作(进阶)。 10、写一个函数完成三次登陆功能,再写一个函数完成注册功能(进阶) 明日默写。 ①,return的作用。 ②,传参的几种方法,每个都简单写一个代码。 如,实参,按位置传参。 def func(x,y): Pass func('a','b')
答案:
2、写函数,检查获取传入列表或元组对象的所有奇数位索引对应的元素,并将其作为新列表返回给调用者。
2.1 先写一个列表,输出索引
data = [1,2,3,4,5] for i in range(len(data)): print(i)
执行输出:
0
1
2
3
4
2.2 判断索引为奇数,打印出来
data = [1,2,3,4,5] for i in range(len(data)): if i % 2 == 1: print(data[i])
执行输出:
2
4
2.3将结果追加到新列表中
data = [1,2,3,4,5] li = [] for i in range(len(data)): if i % 2 == 1: li.append(data[i]) print(li)
执行输出:
[2, 4]
2.4封装成函数,传入列表和元组
def odd_number(data): li = [] for i in range(len(data)): if i % 2 == 1: li.append(data[i]) return li #传入一个列表 li_1 = [1,2,3,4,5] print(odd_number(li_1)) #传入一个元祖 li_2 = ('a','b','c','d') print(odd_number(li_2))
执行输出:
[2, 4]
['b', 'd']
第二种写法:
def func1(argv): return argv[1::2] print(func1([1,2,3,4]))
只有一行,可以缩写,优化代码:
def func1(argv):return argv[1::2] print(func1([1,2,3,4]))
3、写函数,判断用户传入的对象(字符串、列表、元组)长度是否大于5。
3.1 定义一个字符串,使用len()判断长度是否大于5
obj = 'fdskfie' if len(obj) > 5: print(True) else: print(False)
执行输出:
True
3.2 封装成函数
def compare(obj): if len(obj) > 5: return True else: return False obj = 'fdskfie' print(compare(obj))
执行输出:
True
3.3代码精简
def compare(obj): return True if len(obj) > 5 else False obj = 'fdsk' print(compare(obj))
执行输出:
False
3.4 传入的对象(字符串、列表、元组)
def compare(obj): return True if len(obj) > 5 else False str_obj = 'fdsk' print(compare(str_obj)) list_obj = [1,2,3,4,5,6] print(compare(list_obj)) tuple_obj = ('g','k','e','w') print(compare(tuple_obj))
执行输出:
False
True
False
第二种写法,因为它是一个不等式,结果就是True或者False
def func2(argv): return len(argv) > 5 print(func2('fdsfs'))
4、写函数,检查传入列表的长度,如果大于2,那么仅保留前两个长度的内容,并将新内容返回给调用者。
4.1判断列表长度是否大于2,返回切片
li = [1,2,3,4] if len(li) > 2: print(li[:2])
执行输出:
[1, 2]
4.2封装成函数
def list_slicing(li): if len(li) > 2: return li[:2] li = [1, 2, 3, 4] print(list_slicing(li))
执行输出:
[1, 2]
5、写函数,计算传入字符串中【数字】、【字母】、【空格] 以及 【其他】的个数,并返回结果。
5.1使用for循环遍历,并判断类型输出
data = '1 3a &% ' for i in data: if i.isdigit(): print('数字为: {}'.format(i)) elif i.isalpha(): print('字母为: {}'.format(i)) elif i.isspace(): print('空格为: {}'.format(i)) else: print('其他为: {}'.format(i))
执行输出:
数字为: 1
空格为:
数字为: 3
字母为: a
空格为:
其他为: &
其他为: %
空格为:
5.2 增加计数功能
data = '1 3a &% ' #个数统计 digit = 0 letter = 0 space = 0 other = 0 for i in data: if i.isdigit(): digit += 1 elif i.isalpha(): letter += 1 elif i.isspace(): space += 1 else: other += 1 print('数字个数为: {}'.format(digit)) print('字母个数为: {}'.format(letter)) print('空格个数为: {}'.format(space)) print('其他个数为: {}'.format(other))
执行输出:
数字个数为: 2
字母个数为: 1
空格个数为: 3
其他个数为: 2
5.3优化输出
data = '1 3a &% ' #个数统计 digit = 0 letter = 0 space = 0 other = 0 for i in data: if i.isdigit(): digit += 1 elif i.isalpha(): letter += 1 elif i.isspace(): space += 1 else: other += 1 #格式化输出 layout = ''' 数字个数为: {} 字母个数为: {} 空格个数为: {} 其他个数为: {} ''' print(layout.format(digit,letter,space,other))
执行程序,效果同上。
5.4 封装成函数
def counta(data): # 个数统计 digit = 0 letter = 0 space = 0 other = 0 for i in data: if i.isdigit(): digit += 1 elif i.isalpha(): letter += 1 elif i.isspace(): space += 1 else: other += 1 # 格式化输出 layout = ''' 数字个数为: {} 字母个数为: {} 空格个数为: {} 其他个数为: {} ''' return layout.format(digit, letter, space, other) data = '1 3a &% ' print(counta(data))
执行输出:
数字个数为: 2
字母个数为: 1
空格个数为: 3
其他个数为: 2
老师的代码:
def func4(argv): dic = {'digit':0,'aplha':0,'space':0,'other':0} for i in argv: if i.isdigit(): dic['digit'] += 1 elif i.isalpha(): dic['aplha'] += 1 elif i.isspace(): dic['space'] += 1 else: dic['other'] += 1 return '数字{},字母{},空格{},其他{}'.format(dic['digit'],dic['aplha'],dic['space'],dic['other']) print(func4('fdsf 224&&3Tdw ~!wift4t4ttd f'))
执行输出:
数字6,字母16,空格4,其他4
6、写函数,检查用户传入的对象(字符串、列表、元组)的每一个元素是否含有空内容,并返回结果。
6.1用一个变量,使用for循环遍历每一个元素,判断是否为空格
data = '13a &%' for i in data: # 判断内容是否为空 if i == ' ': print('对象含有空格') else: print('对象没有空格!')
执行输出:
对象没有空格!
对象没有空格!
对象没有空格!
对象含有空格
对象没有空格!
对象没有空格!
6.2 使用标志位
data = '13 a&%' for i in data: # 判断内容是否为空 if i == ' ': flag = True break else: flag = False if flag: print('对象含有空格!') else: print('对象没有空格')
执行输出:
对象含有空格!
6.3 封装成函数
def contain_space(data): for i in data: # 判断内容是否为空 if i == ' ': flag = True break else: flag = False if flag: return '对象含有空格!' else: return '对象没有空格' data = '13a&%' print(contain_space(data))
执行输出:
对象含有空格!
6.4代码优化
def contain_space(data): for i in data: # 判断内容是否为空 if i == ' ': flag = True break else: flag = False return '对象含有空格!' if flag else '对象没有空格' data = '13 a&%' print(contain_space(data))
执行输出:
对象含有空格!
7、写函数,检查传入字典的每一个value的长度,如果大于2,那么仅保留前两个长度的内容,并将新内容返回给调用者。
dic = {"k1": "v1v1", "k2": [11,22,33,44]}
PS:字典中的value只能是字符串或列表
7.1遍历字典,并判断values如果大于2,进行切片
dic = {"k1": "v1v1", "k2": [11,22,33,44]} for k,v in dic.items(): if len(v) > 2: #切片 v = v[:2] print(v)
执行输出:
v1
[11, 22]
7.2修改values值
dic = {"k1": "v1v1", "k2": [11,22,33,44]} for k,v in dic.items(): if len(v) > 2: #切片 v = v[:2] #修改values的值 dic[k] = v print(dic)
执行输出:
{'k1': 'v1', 'k2': [11, 22]}
7.3封装成函数
def dictionary(dic): for k,v in dic.items(): if len(v) > 2: #切片 v = v[:2] #修改values的值 dic[k] = v return dic dic = {"k1": "v1v1", "k2": [11, 22, 33, 44]} print(dictionary(dic))
执行输出:
{'k1': 'v1', 'k2': [11, 22]}
老师的代码:
def func7(argv): for i in argv: argv[i] = argv[i][:2] return argv dic = {"k1": "v1v1", "k2": [11, 22, 33, 44]} print(func7(dic))
执行输出,效果同上
8、写函数,接收两个数字参数,返回比较大的那个数字。
老师讲过,直接贴代码
def max_min(a,b): return a if a > b else b print(max_min(5,8))
执行输出:
8
9、写函数,用户传入修改的文件名,与要修改的内容,执行函数,完成整个文件的批量修改操作(进阶)。
9.1 把今天早上的默认的代码贴过来
import os with open('log.txt',encoding='utf-8') as f1, open('log.bak',encoding='utf-8',mode='w') as f2: for i in f1: new_i = i.replace('alex', 'SB') f2.write(new_i) os.remove('log.txt') os.rename('log.bak','log.txt')
9.2封装成函数
''' path 文件路径(此文件python能够找到),比如log.txt content 需要修改的内容,比如aa modify 要替换的内容,比如bb ''' def file_replace(path,content,modify): import os with open(path, encoding='utf-8') as f1, open(path+'.bak', encoding='utf-8', mode='w') as f2: for i in f1: new_i = i.replace(content,modify) f2.write(new_i) os.remove(path) os.rename(path+'.bak', path)
9.3新建一个文件log.txt,内容如下:
人生苦短,我想学python
9.4执行函数
file = 'log.txt' content = 'Python' modify = 'python(最好的语言)' file_replace(file,content,modify)
9.5查看文件内容
10、写一个函数完成三次登陆功能,再写一个函数完成注册功能(进阶)
10.1将上次写的三次登录代码贴过来
username = 'xiao' password = '123' max = 3 i = 0 while i < max: i += 1 name = input('请输入用户名:') pwd = input('请输入密码:') if name == username and pwd == password: print('登陆成功') break else: print('用户名或密码错误,还剩余{}次机会!'.format(max-i))
10.2将用户名与密码存储到字典中,修改登录程序
users = [ {'username':'zhangsan','password':'123'}, {'username':'lisi','password':'123'}, ] max = 3 count = 0 while count < max: count += 1 name = input('请输入用户名:').strip() pwd = input('请输入密码:').strip() for i in users: username = i['username'] password = i['password'] #判断用户名和密码 if name == username and pwd == password: print('登陆成功') #设置标志位 flag = True break else: print('用户名或密码错误,还剩余%s次机会!' % (max-count)) flag = False #判断标志位,跳出循环 if flag: break
10.3执行输出:
10.4封装成函数
users = [ {'username':'zhangsan','password':'123'}, {'username':'lisi','password':'123'}, ] def login(): max = 3 count = 0 while count < max: count += 1 name = input('请输入用户名:').strip() pwd = input('请输入密码:').strip() for i in users: username = i['username'] password = i['password'] #判断用户名和密码 if name == username and pwd == password: print('登陆成功') return True else: print('用户名或密码错误,还剩余%s次机会!' % (max-count)) return False print(login())
10.5执行输出:
10.6写一个注册功能
def register(): while True: reg_user = input('请输入注册用户名: ').strip() reg_pwd1 = input('请输入登录密码: ').strip() reg_pwd2 = input('请再次确认密码: ').strip() #判断2次密码是否一致 if reg_pwd1 == reg_pwd2: #加入到用户列表中 users.append({'username':reg_user,'password':reg_pwd1}) return '注册成功!您注册的用户名为:{} 登录密码为: {}'.format(reg_user,reg_pwd1) else: print('2次密码输入不一致,请重新输入!') return False
10.7执行注册函数
#执行注册 print(register()) #打印用户列表 print(' ') print('当前用户列表'.center(20,'*')) for i in users: print('{} {} {}'.format(users.index(i)+1,i['username'],i['password'])) print(''.center(20,'*'))
10.8执行输出:
完整代码如下:
users = [ {'username':'zhangsan','password':'123'}, {'username':'lisi','password':'123'}, ] def login(): max = 3 count = 0 while count < max: count += 1 name = input('请输入用户名:').strip() pwd = input('请输入密码:').strip() for i in users: username = i['username'] password = i['password'] #判断用户名和密码 if name == username and pwd == password: print('登陆成功') return True else: print('用户名或密码错误,还剩余%s次机会!' % (max-count)) return False def register(): while True: reg_user = input('请输入注册用户名: ').strip() reg_pwd1 = input('请输入登录密码: ').strip() reg_pwd2 = input('请再次确认密码: ').strip() #判断2次密码是否一致 if reg_pwd1 == reg_pwd2: #加入到用户列表中 users.append({'username':reg_user,'password':reg_pwd1}) return '注册成功!您注册的用户名为:{} 登录密码为: {}'.format(reg_user,reg_pwd1) else: print('2次密码输入不一致,请重新输入!') return False #执行登录 #print(login()) #执行注册 print(register()) #打印用户列表 print(' ') print('当前用户列表'.center(20,'*')) for i in users: print('{} {} {}'.format(users.index(i)+1,i['username'],i['password'])) print(''.center(20,'*'))
老师的部分代码:
def register(*args,**kwargs): flag = True while flag: username = input('请输入注册的用户名:').strip() with open('register_msg',encoding='utf-8') as f1: for i in f1: li = i.strip().split() # [张三,123] if username == li[0] or username == '' : print('用户名已存在,请重新注册') break else: password = input('请输入您注册的密码:') with open('register_msg',encoding='utf-8',mode='a') as f2: f2.write(' {} {}'.format(username,password)) print('注册成功') return register() def login(*args,**kwargs): pass login()
明日默写。
①,return的作用。
1.在函数中,遇到return结束函数。
2.将值返回给函数的调用者。
②,传参的几种方法,每个都简单写一个代码。
如,实参,按位置传参。
def func(x,y):
Pass
func('a','b')
1.位置传参。按顺序,一一对应。
def func(a,b): print(a) print(b) func(3,4)
2.关键字传参,不按顺序,一一对应。
def max_min(a,b): return a if a > b else b print(max_min(b = 1,a = 3))
3.混合传参,关键字参数永远在最后面。
def func1(a,b,c): print(a) print(b) print(c) func1(1,4,c=3)
4.默认参数,传参则覆盖,不传则默认
def func(a,b=666): print(a,b) func(1,2)