2020.06.25--预习课--第7节--函数
一、函数
1、为什么要写函数?
减少重复代码的编写,方便修改
2、定义
def 函数名(x,y): # 括号里面可以有参数也可以没有参数;个数:0-多个; 函数体:完成数据操作或者计算的过程 return 计算的结果
练习1:
比较两个数字的大小
>>> def compare_teo_num(x,y): ... if x>y: ... print("%s 大于 %s !",%(x,y)) File "<stdin>", line 3 print("%s 大于 %s !",%(x, y)) ^ SyntaxError: invalid syntax >>> def compare_teo_num(x,y): ... if x>y: ... print("%s 大于 %s !"%(x, y)) ... elif x == y: ... print("%s 等于 %s !"%(x, y)) ... else: ... print("%s 小于 %s !"%(x, y)) ... >>> compare_teo_num(10, 20) 10 小于 20 >>> compare_teo_num(30, 20) 30 大于 20 ! >>> compare_teo_num(20, 20) 20 等于 20 ! >>>
练习2:
打印指定数量的”*“
>>> def print_star(times): ... if isinstance(times, int): ... print('*'*times) ... else: ... return None ... >>> print_star(10) ********** >>> print_star(1) * >>> print_star(5) ***** >>> print_star(50) ************************************************** >>> print_star(50.1) >>> print_star('a') >>>
练习3:
输出两个数字相加的和
>>> def two_num_add(x,y): ... if isinstance(x,(int,float)) and isinstance(y,(int,float)): ... print(x+y) ... else: ... return None ... >>> two_num_add(10,-8) 2 >>> two_num_add(10,8) 18 >>> two_num_add(-10,8) -2 >>> two_num_add(-10,'a') >>> two_num_add(-10,5.5) -4.5 >>>
# 少参数 >>> two_num_add(1) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: two_num_add() missing 1 required positional argument: 'y' >>> two_num_add() Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: two_num_add() missing 2 required positional arguments: 'x' and 'y' # 参数传多了 >>> two_num_add(1,2,3) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: two_num_add() takes 2 positional arguments but 3 were given # 参数数量正好 >>> two_num_add(1,2) 3 >>>
3、命名参数
>>> def print_parameter(a,b): ... print('a:',a) ... print('b:',b) ... >>> print_parameter(10,100) a: 10 b: 100 >>> print_parameter(b=10,a=100) a: 100 b: 10 >>>
# 参数解包 >>> d = {'a':5,'b':25} >>> print_parameter(**d) # 等价于 add(b=25,a=5) a: 5 b: 25 >>>
4、函数的默认值,如果不传,输出默认值,如果传,则覆盖替换。默认值必须要放在非默认值的后面。
>>> def print_something(a,b='world!'): ... print(a,b) ... >>> print_something('hello ') hello world! >>> >>> print_something('hello ','Mary!') hello Mary! >>>
5、可变参数:多余的参数以元组的形式传入,*拿到的值只能是tuple,不能是别的
>>> def print_parameters(a,b,*c): ... print(type(c), c) ... >>> print_parameters(1,2,3,4,5) <class 'tuple'> (3, 4, 5) >>> print_parameters(1,2,3,4,5,6,7,8) <class 'tuple'> (3, 4, 5, 6, 7, 8) >>>
练习:
输出所有的传入数字的加和
>>> def add_all_parameters(a,b,*c): ... print(c) ... sum = a+b ... for i in c: ... sum = sum+i ... return sum ... >>> add_all_parameters(1,2) () 3 >>> add_all_parameters(1,2,3) (3,) 6 >>> add_all_parameters(1,2,3,4) (3, 4) 10 >>> add_all_parameters(1,2,3,4,5) (3, 4, 5) 15 >>> add_all_parameters(1,2,3,4,5,6) (3, 4, 5, 6) 21
6、可变参数以字典的形式传入到函数中
>>> def check_parameter(a,b,**kw): ... print(type(kw), kw) ... # 需要一致,符合传参规则,只需要a,b两个,不能传入三个 >>> check_parameter(1,2,3,c=4,d=5) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: check_parameter() takes 2 positional arguments but 3 were given >>> check_parameter(1,2,e=3,c=4,d=5) <class 'dict'> {'e': 3, 'c': 4, 'd': 5} >>>
练习:
求传入字典形式的所有参数加和
>>> def add_dict_parameters(a,b,**kw): ... sum = a+b ... print(kw) ... for v in kw.values(): ... sum += v ... return sum ... >>> add_dict_parameters(1,2) {} 3 # 多的参数命名不能与前面的参数名重复 >>> add_dict_parameters(1,2,b=3) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: add_dict_parameters() got multiple values for argument 'b' >>> add_dict_parameters(1,2,c=3) {'c': 3} 6 >>> add_dict_parameters(1,2,c=3,d=4) {'c': 3, 'd': 4} 10 >>> add_dict_parameters(1,2,c=3,d=4,e=5) {'c': 3, 'd': 4, 'e': 5} 15 >>> add_dict_parameters(1,2,c=3,d=4,e=5,f=6) {'c': 3, 'd': 4, 'e': 5, 'f': 6} 21 >>>
ps:
不确定的参数传入到元组或者字典中
7、参数形式混用
练习:
各种传入参数的求和
>>> def add_all_parameter(*args,**kw): ... sum = 0 ... for i in args: ... sum += i ... for v in kw.values(): ... sum += v ... return sum ... >>> add_all_parameter(1,2) 3 >>> add_all_parameter(1) 1 >>> add_all_parameter(1,2,3) 6 >>> add_all_parameter(1,2,3,a=4) 10 >>> add_all_parameter(1,2,3,a=4,b=5) 15 >>> add_all_parameter(1,2,3,a=4,b=5,c=6) 21 >>>
8、map 函数:map(函数对象,序列)
map:表示把序列中的每一个元素,依次(分别)传给函数去做处理,处理后,放到一个list中
ps:
序列:列表、元组、字符串
>>> list('abc') ['a', 'b', 'c'] # list 不能直接转义数字类型 >>> list(123) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'int' object is not iterable >>> list('123') ['1', '2', '3'] >>> list((1,2,3)) [1, 2, 3] >>> str(123) '123' >>> str((1,2)) '(1, 2)' >>> str([1,2]) '[1, 2]' >>> tuple('abc') ('a', 'b', 'c') >>> tuple('123') ('1', '2', '3') # 元组也不能直接转义数字类型 >>> tuple(123) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'int' object is not iterable >>> tuple([1,2]) (1, 2) >>>
>>> map(str,[1,2,3]) <map object at 0x1076e2630> >>> list(map(str,[1,2,3])) ['1', '2', '3'] >>> for i in map(str,[1,2,3]): ... print(type(i),i) ... <class 'str'> 1 <class 'str'> 2 <class 'str'> 3 >>>
>>> map(int,['1','2','3']) <map object at 0x1076a5b70> >>> >>> list(map(int,['1','2'])) [1, 2] >>>
8.1、map 与自定义函数,map是个类
# 定义一个自定义函数 >>> def add(num): ... return num+10 ... # 在 map 中使用这个自定义函数 >>> map(add,[1,2,3]) <map object at 0x1076a5b70> >>> list(map(add,[1,2,3])) [11, 12, 13] >>>
# 正常定义的函数类型 >>> type(add) <class 'function'> # map 不是函数,是个类,迭代对象 >>> type(map) <class 'type'> >>>
9、filter:过滤函数----filter(函数对象,序列)
序列中的每一个元素,也会一次传递给函数对象,函数对象如果返回的值代表True,那么这个序列的元素会被保留,是False则元素呗丢弃
# 自定义一个判断数字的函数 >>> def is_num(num): ... if isinstance(num,(int,float)): ... return True ... return False ... # 在filter中使用该自定义函数,如果是True的元素就会保留,False的就会被丢弃 >>> list(filter(is_num,[1,2,'a','b'])) [1, 2] >>>
10、匿名函数 lambda && reduce ; lambda是内置关键字??
# 需要引入包 >>> from functools import reduce >>> a = lambda x:x+1 >>> type(a) <class 'function'> >>> a(1) 2 >>> a = lambda x,y:x+y >>> a(1,2) 3 >>> >>> b = lambda x,y:x+y # 缺少参数y >>> b(1) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: <lambda>() missing 1 required positional argument: 'y' >>> b(1,2) 3 # 只传入一个参数为何可以正常计算??跟reduce有关?? >>> reduce(b,[1]) 1 >>> reduce(b,[1,2]) 3 >>>
>>> map(lambda x:x+10,[1,2,3]) <map object at 0x1076a5dd8> >>> list(map(lambda x:x+10,[1,2,3])) [11, 12, 13] >>>
练习:
一行代码将小写字母转化为大写字母
>>> list(map(lambda x:x.upper(),['a','b'])) ['A', 'B'] >>>
>>> list(map(lambda x:chr(ord(x)-32),['a','z'])) ['A', 'Z'] >>>
不懂得地方
# 这个系列里只有一个值,计算返回了1 >>> reduce(lambda x,y:x+y,[1]) 1 # 如果是这么计算,那么没有报错 >>> lambda x,y:x+y([1]) <function <lambda> at 0x107864378> # but如果lambda赋给b,只传入一个[1],就报错了 >>> b = lambda x,y:x+y >>> b([1]) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: <lambda>() missing 1 required positional argument: 'y' >>>