函数、递归函数、纯函数、内置函数、匿名函数、偏函数
1、函数
如何定义一个函数
- 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号()。
- 任何传入参数和自变量必须放在圆括号中间。圆括号之间可以用于定义参数。
- 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
- 函数内容以冒号起始,并且缩进。
- return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。
def method(a): ''' 这是一个测试方法 :param a: :return: ''' a=10+1 return a
参数:
(1)必需参数:
def sumdata(a,b): #a,b 形式参数,简称形参 return a+b print(sumdata(34,56)) #实际参数,简称实参 print(sumdata(a=34,b=56)) #实参的完整写法,当使用完整写法时,参数的顺序可以进行调换 print(sumdata(34,b=56)) #前面用简写,后面用完整写法 print(sumdata(a=34,56)) #错误的写法:前面用完整写法,后面用简写
(2)默认参数
def sumdata(a,b,c=100): return a+b+c print(sumdata(12,35,c=1)) # 48 print(sumdata(12,35)) #147
(3)可变长度参数 *args,可以传入若干个参数
def sumdata(a,*args): # return (a,args) #会多一层元组 (3, (4, 5)) return (a,*args) #不会多一层元组 进行了解包 (3, 4, 5) print(sumdata(3,4,5))
(4)关键字参数 **kwargs,它是一个字典 **kwargs也可以写任意个值,但必须成对出现,
#如果有*args的情况,它必须位于*args的后面
def fun5(a, *args, **kwargs): return (a, *args, kwargs) print(fun5(100, 22, 33, 79, aa=98,bb=99,cc=100)) # (100, 22, 33, 79, {'aa': 98, 'bb': 99, 'cc': 100}) print(fun5(100, 22, 33, 79, **{"aa":98,"bb":99,"cc":100})) #(100, 22, 33, 79, {'aa': 98, 'bb': 99, 'cc': 100})
参数中传参:
传不可变对象
def ChangeInt(a): a = 10 b = 2 ChangeInt(b) print(b) # 结果是 2
传可变对象
def changeme(mylist): "修改传入的列表" mylist.append([1, 2, 3, 4]) print("函数内取值: ", mylist) return # 调用changeme函数 mylist = [10, 20, 30] changeme(mylist) print("函数外取值: ", mylist)
结果:
2、递归函数
递归函数就是函数在内部调用自身。
必须有一个明确的递归结束条件,称为递归出口。
注意: 递归函数一定要写终止条件,否则将产生无限递归(死循环)
递归函数实现阶乘:n! = 1 * 2 * 3 * ... * n
def fact(n): if n == 1: return 1 return n * fact(n - 1) print(fact(5)) # 输出结果: 120 print(fact(1)) # 输出结果: 1
递归函数实现斐波那契数列:[1,1,2,3,5,8....]
兔子繁殖问题:兔子三个月起每个月生一只小兔子,小兔子长到三个月后每个月有生一直兔子,假如兔子都不死,那么第一个月从一只小兔子到N个月后,问兔子的总数为多少?
def fib(n): if n==1 or n==2: return 1 else: return fib(n-1)+fib(n-2) print(fib(5)) #输出结果:5 print(fib(6)) #输出结果:8
总结来说,使用递归函数的优点是逻辑简单清晰, 缺点是过深的调用会导致栈溢出(即比较占用内存空间).(python默认最大为1000次递归)
2、纯函数
一个函数的返回值只依赖于他的参数,并且在执行过程里面没副作用,这个函数就叫纯函数。
纯函数的3个原则:
- 变量都只在函数作用域内获取,作为函数的参数传入
- 不会产生副作用,不会改变被传入的数据或者其他数据(全局变量)
- 相同的输入保证相同的输出
函数的副作用是指函数被调用,完成了函数既定的计算任务,但同时因为访问了外部数据,尤其是因为对外部数据进行了写操作,从而一定程度改变了系统环境。
#函数1的返回结果为两个参数相加的结果 def func1(a,b): return a+b
3、内置函数
参考https://www.runoob.com/python/python-built-in-functions.html
filter:过滤函数,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表。
#过滤函数,第一个参数为函数,第二个参数为可迭代对象 res=filter(fun,[1,3,5,7,9,11,40]) print(res) #运行结果:<filter object at 0x10d84be80> print(list(res)) #运行结果:[7, 9, 11, 40]
map:将可迭代对象中的数据迭代出来,一个个调用函数,并将返回结果存到新的对象中
def fun(n): return n>5 res=map(fun,[1,3,6,8,11,20]) print(res) #运行结果:<map object at 0x10f0b6198> print(list(res)) #运行结果:[False, False, True, True, True, True]
zip:打包函数,用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。
如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同。
a=[1,2,3,4,5] b=[6,7,8,9,10] c=[1,2,3] d=[1,2,3,4,5,6,7] res1=zip(a,b) res2=zip(a,c) res3=zip(a,d) print(res1) #运行结果:<zip object at 0x10c9e0d08> print(list(res1)) #运行结果:[(1, 6), (2, 7), (3, 8), (4, 9), (5, 10)] print(list(res2)) #运行结果:[(1, 1), (2, 2), (3, 3)] print(list(res3)) #运行结果:[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5)]
4、匿名函数
匿名函数语法:lambda arg1,arg2,.....argn:expression
# 冒号:之前的a,b,c表示它们是这个函数的参数。
# 匿名函数不需要return来返回值,表达式本身结果就是返回值。
#无参匿名函数 f=lambda :True print(f()) #运行结果:True #有参匿名函数 lambda x: x**3 #一个参数 lambda x,y,z:x+y+z #多个参数 lambda x,y=3: x*y #允许参数存在默认值 a = lambda *z:z #*z返回的是一个元祖 print(a('Testing1','Testing2')) # 运行结果:('Testing1', 'Testing2') #配合filter函数使用 f=filter(lambda x:x>5,[1,3,5,7,8,9]) print(list(f)) #运行结果:[7, 8, 9]
5、偏函数
当函数的参数个数太多,需要简化时,可以使用functools.partail创建一个新函数,这个函数可以固定住原函数的部分参数。
from functools import partial li=[1,2,3,4,7,8,9,11] li1=[1,2,32,41,17,18,19,11] li2=[3,4,17,28,19,111] li3=[4,7,2,6,71,82,91,1221] li4=[11,21,113,14,71,38,3,0] # f=filter(lambda x:x>5,li) # f1=filter(lambda x:x>5,li1) # f2=filter(lambda x:x>5,li2) # f3=filter(lambda x:x>5,li3) # f4=filter(lambda x:x>5,li4) filter2=partial(filter,lambda x:x>5) # 固定参数,传入函数名和参数 f=filter2(li) print(list(f)) # 运行结果:[7, 8, 9, 11]
posted on 2020-08-19 10:23 crystal1126 阅读(212) 评论(0) 编辑 收藏 举报