函数—函数进阶—作业需求
1 ''' 2 1、编码问题 3 请说明python2 与python3中的默认编码是什么? 4 python2:ASCII 5 python3:UTF—8 6 为什么会出现中文乱码?你能列举出现乱码的情况有哪几种? 7 存到硬盘上时是以何种编码存的,再从硬盘上读出来时,就必须以何种编码读,不然就会出现中文乱码。 8 终端为UTF-8,locale为zh_CN.GBK 9 终端为UTF-8,locale为zh_CN.UTF-8 10 终端为GBK,locale为zh_CN.GBK 11 终端为GBK,locale为zh_CN.UTF-8 12 如何进行编码转换? 13 UTF-8 --> decode 解码 --> Unicode 14 Unicode --> encode 编码 --> GBK / UTF-8 15 #-*-coding:utf-8-*- 的作用是什么? 16 声明编码为:utf_8 17 解释py2 bytes vs py3 bytes的区别 18 python2 str == bytes 19 python3 中需要通过 unicode 20 string -> encode -> bytes 21 bytes -> decode -> string 22 23 2、文件处理 24 r和rb的区别是什么? 25 r 为 读模式 26 rb 为 二进制读模式 27 解释一下以下三个参数的分别作用,open(f_name,'r',encoding="utf-8") 28 f_name 文件名 29 r 模式 30 encoding 编码方式 31 '''
3、函数基础
-
写函数,计算传入数字参数的和。(动态传参)
1 def sum(x,y): 2 sum = x + y 3 print(sum) 4 sum(2,3) 5 6 lambda x,y : x+y
-
写函数,用户传入修改的文件名,与要修改的内容,执行函数,完成整个文件的批量修改操作。
1 def func(): 2 name = input("要修改的文件名:") 3 content = input("要修改的内容:") 4 content1 = input("修改后的内容:") 5 new_name = name+'.new' 6 7 import os #加载模块 8 f = open(name,mode = 'r') #打开要修改的文件 9 f_new = open(new_name,mode = 'w') #打开修改后写入的文件 10 11 for i in f: #循环文件中每一行的的数据 12 if content in i: 13 new_i = i.replace(content,content1) #将要修改的内容字符串用replace替换 14 else: 15 new_i = i 16 f_new.write(new_i) 17 f.close() #关闭要修改的文件 18 f_new.close() #关闭修改后写入的文件 19 os.rename(new_name,name) #将写入修改后内容的文件改名为修改的文件名,这样就相当于修改了原来的文件 20 func()
-
写函数,检查用户传入的对象(字符串、列表、元组)的每一个元素是否含有空内容。
1 def func(*file): 2 n = 0 3 for i in file: 4 if i == ' ': 5 n += 1 6 print("含有%s个空行"%n) 7 func(*[1,' ',2])
-
写函数,检查传入字典的每一个value的长度,如果大于2,那么仅保留前两个长度的内容,并将新内容返回给调用者。
dic = {"k1": "v1v1", "k2": [11,22,33,44]}
PS:字典中的value只能是字符串或列表1 dic = {"k1": "v1v1", "k2": [11,22,33,44]} 2 def func(dic): 3 for i in dic: 4 if len(dic[i]) > 2: 5 dic[i] = dic[i][:2] 6 return dic 7 f = func(dic) 8 print(f)
-
解释闭包的概念。
1 闭包:即函数定义和函数表达式位于另一个函数的函数体内(嵌套函数)。 2 这些内部函数可以访问它们所在的外部函数中声明的所有局部变量、参数。 3 当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包。 4 也就是说,内部函数会在外部函数返回后被执行。而当这个内部函数执行时,它仍然必需访问其外部函数的局部变量、参数以及其他内部函数。 5 这些局部变量、参数和函数声明(最初时)的值是外部函数返回时的值,但也会受到内部函数的影响 6 7 例: 8 def func(): 9 n = 10 10 11 def func2(): 12 print("func2:",n) 13 return func2 #返回func2的内存地址 14 15 f = func() 16 print(f) #结果为:<function func.<locals>.func2 at 0x000002F1B9F59730> 17 f() #结果为:func2: 10 18 19 #按常理来讲,执行完func()函数后,func2()已经释放了,但是它返回了 func2: 10 20 #在外部拿到了内部的函数,并且还可以使用内部函数的作用域里面的值 21 22 #闭包的意义:返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域
4、函数进阶
-
写函数,返回一个扑克牌列表,里面有52项,每一项是一个元组,例如:[(‘红心’,2),(‘草花’,2), …(‘黑桃A’)]
1 def func(): 2 num = [] 3 for i in range(2,11): 4 num.append(i) 5 num.extend(['J','Q','K','A']) 6 data = ['红心','草花','方块','黑桃'] 7 num1 = [] 8 for i in num: 9 for j in data: 10 num1.append((j,i)) 11 return num1 12 f = func() 13 print(f)
-
写函数,传入n个数,返回字典{‘max’:最大值,’min’:最小值}。例如:min_max(2,5,7,8,4),返回:{‘max’:8,’min’:2}
1 def min_max(*args): 2 max = args[0] 3 min = args[0] 4 for i in args: 5 if i > max: 6 max = i 7 elif i < min: 8 min = i 9 return {'max': max , 'min': min} 10 print(min_max(3,2,6,8,15,17,-9,38,5))
-
写函数,专门计算图形的面积
1 # 其中嵌套函数,计算圆的面积,正方形的面积和长方形的面积 2 # 调用函数area(‘圆形’,圆半径) 返回圆的面积 3 # 调用函数area(‘正方形’,边长) 返回正方形的面积 4 # 调用函数area(‘长方形’,长,宽) 返回长方形的面积 5 # def area(): 6 # def 计算长方形面积(): 7 # pass 8 # 9 # def 计算正方形面积(): 10 # pass 11 # 12 # def 计算圆形面积(): 13 # pass 14 def area(): 15 def rectangle(x,y): 16 print(x*y) 17 def square(s): 18 print(s*s) 19 def circle(r): 20 print(3.14*r*r) 21 22 name = input('请输入图形名称:') 23 if name == '长方形': 24 x = int(input('请输入长方形的长:')) 25 y = int(input('请输入长方形的宽:')) 26 rectangle(x,y) 27 elif name == '正方形': 28 s = int(input('请输入正方形的边长:')) 29 square(s) 30 elif name == '圆形': 31 r = int(input('请输入圆的半径:')) 32 circle(r) 33 print(area())
-
写函数,传入一个参数n,返回n的阶乘。
1 def func2(n): 2 res = 1 3 for i in range(n,0,-1): 4 res = res * i 5 return res 6 print(func2(5))
-
编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,后续的函数都无需再输入用户名和密码。
1 user_status = False # 用户登录了,就把这个改成True 2 def login(auth_type): 3 def iner(): 4 global user_status 5 if user_status == False: 6 username = input("user:") 7 password = input("password:") 8 9 f = open('data.txt','r') 10 da = eval(f.read()) 11 if username in da: 12 if password == da[username]: 13 user_status = True 14 if user_status == True: 15 auth_type() 16 return iner 17 18 @login 19 def func(): 20 print('---func---') 21 @login 22 def func1(): 23 print('----func1----') 24 @login 25 def func2(): 26 print('-----func2----') 27 28 @login 29 def func3(): 30 print('-----func3----') 31 32 func() 33 func3()
5、生成器和迭代器
-
生成器和迭代器的区别?
1 对于list、string、tuple、dict等这些容器对象,使用for循环遍历是很方便的。在后台for语句对容器对象调用iter()函数。iter()是python内置函数。 2 iter()函数会返回一个定义了next()方法的迭代器对象,它在容器中逐个访问容器内的元素。next()也是python内置函数。在没有后续元素时,next()会抛出一个StopIteration异常,通知for语句循环结束。 3 迭代器是用来帮助我们记录每次迭代访问到的位置,当我们对迭代器使用next()函数的时候,迭代器会向我们返回它所记录位置的下一个位置的数据。实际上,在使用next()函数的时候,调用的就是迭代器对象的_next_方法(Python3中是对象的_next_方法, Python2中是对象的next()方法)。所以,我们要想构造一个迭代器,就要实现它的_next_方法。但这还不够,python要求迭代器本身也是可迭代的,所以我们还要为迭代器实现_iter_方法,而_iter_方法要返回一个迭代器,迭代器自身正是一个迭代器,所以迭代器的_iter_方法返回自身self即可。 4 5 6 生成器是一种特殊的迭代器,生成器自动实现了“迭代器协议”(即__iter__和next方法),不需要再手动实现两方法。 7 生成器在迭代的过程中可以改变当前迭代值,而修改普通迭代器的当前迭代值往往会发生异常,影响程序的执行。
-
生成器有几种方式获取value?
1 三种方式获取: 2 while 会报错 3 for 循环 4 next 获取
-
通过生成器写一个日志调用方法, 支持以下功能
根据指令向屏幕输出日志
根据指令向文件输出日志
根据指令同时向文件&屏幕输出日志
以上日志格式如下
2017-10-19 22:07:38 [1] test log db backup 3 2017-10-19 22:07:40 [2] user alex login success #注意:其中[1],[2]是指自日志方法第几次调用,每调用一次输出一条日志
1 def logger(filename,channel='file'): 2 """ 3 日志方法 4 :param filename: log filename 5 :param channel: 输出的目的地,屏幕(terminal),文件(file),屏幕+文件(both) 6 :return: 7 """ 8 ...your code... 9 10 #调用 11 log_obj = logger(filename="web.log",channel='both') 12 log_obj.__next__() 13 log_obj.send('user alex login success')
6、内置函数
-
用map来处理字符串列表,把列表中所有人都变成sb,比方alex_sb
1 #map 它接收一个函数 f 和一个 list,并通过把函数 f 依次作用在 list 的每个元素上,得到一个新的 list 并返回。map()函数在不改变原有的lisy,而是返回一个新的list 2 print(map(lambda x: x*x , [1,2,3,4,5])) #结果为:<map object at 0x0000022DB38384A8> 3 print(list(map(lambda x: x*x , [1,2,3,4,5]))) #结果为:[1, 4, 9, 16, 25] 4 5 #解答: 6 name=['alex','wupeiqi','yuanhao','nezha'] 7 def func(x): 8 return x + '_sb' 9 res = map(func,name) 10 print(list(res))
-
用filter函数处理数字列表,将列表中所有的偶数筛选出来
1 #filter 2 print(filter(lambda x: x>3 , [1,2,3,4,5])) #结果为:<filter object at 0x000002B9B1CC84E0> 3 print(list(filter(lambda x: x>3 , [1,2,3,4,5]))) #结果为:[4, 5] 4 5 #解答 6 num = [1,3,5,6,7,8] 7 def func(x): 8 if x%2 == 0: 9 return x 10 res = filter(func,num) 11 print(list(res))
-
如下,每个小字典的name对应股票名字,shares对应多少股,price对应股票的价格
portfolio = [ {'name': 'IBM', 'shares': 100, 'price': 91.1}, {'name': 'AAPL', 'shares': 50, 'price': 543.22}, {'name': 'FB', 'shares': 200, 'price': 21.09}, {'name': 'HPQ', 'shares': 35, 'price': 31.75}, {'name': 'YHOO', 'shares': 45, 'price': 16.35}, {'name': 'ACME', 'shares': 75, 'price': 115.65} ]
1 #计算购买每支股票的总价 2 for i in portfolio: 3 print(i['name'],i['shares']*i['price']) 4 #或者 5 print([(item['name'],item['shares']*item['price']) for item in portfolio])
1 #用filter过滤出,单价大于100的股票有哪些 2 portfolio = [ 3 {'name': 'IBM', 'shares': 100, 'price': 91.1}, 4 {'name': 'AAPL', 'shares': 50, 'price': 543.22}, 5 {'name': 'FB', 'shares': 200, 'price': 21.09}, 6 {'name': 'HPQ', 'shares': 35, 'price': 31.75}, 7 {'name': 'YHOO', 'shares': 45, 'price': 16.35}, 8 {'name': 'ACME', 'shares': 75, 'price': 115.65} 9 ] 10 print(list(filter(lambda i:i['price'] >100,portfolio)))
7、请分别介绍文件操作中不同的打开方式之间的区别:
1 模式 含义 2 r 文本只读模式 3 rb 二进制模式,这种方法是用来传输或存储,不给人看的 4 r+ 读写模式,只要有r,那么文件必须存在 5 rb+ 二进制读写模式 6 w 只写模式,不能读,用w模式打开一个已经存在的文件,如果有内容会清空,重新写 7 wb 以二进制方式打开,只能写文件,如果不存在,则创建 8 w+ 读写模式,先读后写,只要有w,会清空原来的文件内容 9 wb+ 二进制读写模式 10 a 追加模式,也能写,在文件的末尾添加内容 11 ab 二进制追加模式 12 a+ 追加模式,如果文件不存在,则创建文件,如果存在,则在末尾追加 13 ab+ 追读写二进制模式,从文件顶部读取文件,从文件底部添加内容,不存在则创建
8、有列表 li = ['alex', 'egon', 'smith', 'pizza', 'alen'], 请将以字母“a”开头的元素的首字母改为大写字母
1 # startswith a.startsWith(b) 判断字符串a 是不是以字符串b开头. 2 # append 在被选元素的结尾(仍然在内部)插入指定内容. 3 # capitalize 返回一个字符串,首字母为大写,其他字母为小写 4 li = ['alex', 'egon', 'smih', 'pizza', 'alen'] 5 #方法一: 6 new_li = [] 7 for i in li: 8 if i.startswith('a'): 9 new_li.append(i.capitalize()) 10 else: 11 new_li.append(i) 12 print(new_li) 13 14 #方法二: 15 for i in range(len(li)): 16 if li[i][0] == 'a': 17 li[i] = li[i].capitalize() 18 else: 19 continue 20 print(li) 21 22 #方法三: 23 print([item.capitalize() if item.startswith('a') else item for item in li])
9、有如下程序, 请给出两次调用show_num函数的执行结果,并说明为什么:
1 num = 20 2 def show_num(x=num): 3 print(x) 4 5 show_num() #结果为:20 6 7 num = 30 8 show_num() #结果为:20 9 10 # 如果函数收到的是一个不可变对象(比如数字、字符或者元组)的引用,就不能直接修改原始对象,相当于通过“传值’来传递对象 11 #如果想改变这些变量的值,可以将这些变量申明为全局变量
10、有列表 li = ['alex', 'egon', 'smith', 'pizza', 'alen'], 请以列表中每个元素的第二个字母倒序排序
#sorted((1,4,8,9,3,6), reverse=True) #结果为: [9, 8, 6, 4, 3, 1] li = ['alex', 'egon', 'smith', 'pizza', 'alen'] print(sorted(li,key=lambda x : x[1],reverse = True))
11、有名为poetry.txt的文件,其内容如下,请删除第三行
1 ''' 2 昔人已乘黄鹤去,此地空余黄鹤楼。 3 4 黄鹤一去不复返,白云千载空悠悠。 5 6 晴川历历汉阳树,芳草萋萋鹦鹉洲。 7 8 日暮乡关何处是?烟波江上使人愁。 9 ''' 10 import os 11 f1=open('poetry.txt', 'r',encoding='utf-8') 12 13 str='晴川历历汉阳树,芳草萋萋鹦鹉洲。' 14 with open('poetry1.txt', 'w', encoding='utf-8') as f2: 15 ff1='poetry.txt' 16 ff2='poetry1.txt' 17 for line in f1: 18 if str in line: 19 line='' 20 f2.write(line) 21 22 else: 23 f2.write(line) 24 f1.close() 25 f2.close() 26 os.replace(ff2,ff1)
12、有名为username.txt的文件,其内容格式如下,写一个程序,判断该文件中是否存在"alex", 如果没有,则将字符串"alex"添加到该文件末尾,否则提示用户该用户已存在。
pizza
alex
egon
1 with open('username.txt','r+',encoding='utf-8')as f: 2 s = 'alex' 3 i = f.read() 4 print(i) 5 if s in i: 6 print('该用户已存在') 7 else: 8 f.write('\nalex')
13、有名为user_info.txt的文件,其内容格式如下,写一个程序,删除id为100003的行
1 f_name = r'user_info.txt' 2 f_new_name = '%s.new'%f_name 3 del_id = '100001' 4 f_new = open(f_new_name, 'w', encoding='utf-8') 5 with open(f_name, 'r', encoding='utf-8') as f: 6 for line in f: 7 if del_id in line: 8 pass 9 else: 10 f_new.write(line) 11 f_new.close() 12 os.replace(f_new_name,f_name)
14、有名为user_info.txt的文件,其内容格式如下,写一个程序,将id为100002的用户名修改为alex li
1 f_name = r'user_info.txt' 2 f_new_name = '%s.new'%f_name 3 update_id = '100002' 4 update_name = 'alex li' 5 f_new = open(f_new_name, 'w', encoding='utf-8') 6 with open(f_name, 'r', encoding='utf-8') as f: 7 for line in f: 8 if update_id in line: 9 line = ','.join([update_name, update_id]) 10 f_new.write(line+'\n') 11 else: 12 f_new.write(line) 13 f_new.close() 14 os.replace(f_new_name,f_name)