当前位置: 首页 > Linux

[Python]-7-函数(中)

时间:2023-04-06 02:54:09 Linux

简介本文介绍了python中函数的基础知识。文章目录0×5。递归函数0×6。生成器函数0×7。高阶函数a.map和reduceb.filterc.sorted0×5。递归函数递归函数有点类似于循环。简单的说,就是函数在运行过程中再次调用自己,并通过这个调用来进行一些类似循环的工作,我们来看数学中的一个阶乘算法:我们知道一个数的阶乘可以写为:n!=1×2×3×...×(n-1)×n=n×(n-1)!比如5的阶乘:5!=1×2×3×4×5=5×4!易于实现,例如:#!/usr/bin/envpython#coding=utf-8#--------deffact(n):"""Computen!"""s=1whilen>1:s*=nn-=1returns#计算3的阶乘print(fact(3))#程序输出6并且在一些没有循环的编程语言中,这个算法是通过递归实现的的函数,例如:01#!/usr/bin/envpython02#coding=utf-803#-------04deffact(n):05"""n!=n*fact(n-1)!"""06ifn==1:07return108returnn*fact(n-1)0910print(fact(3))运行这个程序会得到和循环一样的结果,这个递归的执行流程函数如下:fact(3)3*fact(3-1)3(2fact(2-1))3(21)3*26递归函数虽然好用,但是容易造成“栈溢出”》在python中使用递归函数时(这时我们传递一个比较大的数据,比如999的阶乘),处理“栈溢出”的一种方法是使用“尾递归”,但是Python解释器并没有提供支持“尾递归”优化,如果python支持“尾递归”优化,那么上面的递归函数可以改成如下:#!/usr/bin/envpython#coding=utf-8#-------deffact(n):"""计算n!"""returnfact_a(n,1)#--------deffact_a(n,result):如果n==1:返回结果returnfact_a(n-1,n*result)print(fact(6))在上面的fact_a(n,result)函数中使用了“尾递归”优化,返回时调用函数本身,return语句不包含expression,只有函数本身,n-1和n*result这两个参数在调用函数前会被计算。在支持尾递归优化的编程语言中,这种调用方式阻止了栈的增长,因此可以很容易的避免“栈溢出”(但是Python中没有提供这个功能,所以使用递归函数时要谨慎在Python中)0×6。生成器函数“Generatorfunction”有点类似于前面介绍的“列表生成器”。每次迭代此生成器函数时,都会执行算法以计算下一个值。请看下面的例子:#首先我们来看一个普通的函数,传入一个数值num,打印出num位的斐波那契数列#!/usr/bin/envpython#coding=utf-8deffibo(num):#与a=0b=1n=0a,b,n=0,1,0whilen#如果要迭代这个generator中的值,可以使用next()函数,或者使用for循环forxinfibo(5):print(x)#Output11235#也许你会发现问题。迭代后,fibo的最后一条return语句根本没有执行。这是因为生成函数在迭代过程中遇到yield会返回,不会执行后面的内容,再次访问这个生成表达式时,会在上次yield返回的位置继续执行。如果要获取生成函数的return返回值,需要使用next()函数对其内容进行迭代,然后捕获StopIteration异常,这个return包含在异常的值中,例如:#!/usr/bin/envpython#coding=utf-8deffibo(num):a,b,n=0,1,0whilen#虽然没有添加异常处理模块,但是我们使用map函数和reduce函数完成了一个int()函数原型。假设Python没有提供int()函数,你完全可以自己写一个字符串转整数的函数,就像上面的b。filter类似于map(),filter()也接收一个函数和一个序列。与map()不同的是,filter()依次对每个元素应用传入函数,然后根据返回值是True还是False来决定保留还是丢弃该元素,例如:#Example1:Returnodd-numberedlist#!/usr/bin/envpython#coding=utf-8#--------defis_odd(x):"""如果x为奇数则返回True,偶数则返回False"""returnx%2==1L=[1,2,3,4,5,6,7,8]print(list(filter(is_odd,L)))#程序输出[1,3,5,7]#示例2:删除列表Emptystring#!/usr/bin/envpython#coding=utf-8#------defis_sp(x):"""strip()函数可以删除和之前的空格数据后,如果是空字符去掉空格后return返回False,任何非空字符返回True"""returnx.strip()L=["","a","b","","c"]print(list(filter(is_sp,L)))#程序输出['a','b','c']#例3:输出1000以内的所有次数(次数为像121、131,前后对称)#!/usr/bin/envpython#coding=utf-8#------defis_back(x):"""判断是否为后数,将传入的数字转换成字符串然后使用切片进行反转,将转换后的数字重新转换为整数并与原始数字进行比较。[::-1]步长为正数表示从前到后取,步长为负数表示从后到前。"""returnx==int(str(x)[::-1])print(list(filter(is_back,range(1,1001))))c.sortedPython内置的sorted()函数可以用来对可迭代类型(列表等)进行排序,请看下面的例子:#默认情况下,数字是从小到大,字母是先大写后小写的字母顺序>>>L0=[1,-10,9,-2,23,-9]>>>打印(排序(L0))[-10、-9、-2、1、9、23]>>>L1=["B","a","C","d","b","X"]>>>print(sorted(L1))['B','C','X','a','b','d']#sorted是一个高阶函数,可以传递一个key关键字函数,先用这个函数作用于列表的每个元素,然后按照默认排序。本例中使用abs函数将列表的每个元素转化为正整数,然后按照默认的从小到大排序。确定好位置后,再将原列表对应的数字放到相应的位置>>>print(sorted(L0,key=abs))[1,-2,9,-9,-10,23]#Convert列表中的所有字母小写排序>>>print(sorted(L1,key=str.lower))['a','B','b','C','d','X']#使用reverse参数进行反向排序>>>print(sorted(L1,key=str.lower,reverse=True))['X','d','C','B','b','a']再来看一个例子,使用自定义函数对列表进行排序:#!/usr/bin/envpython#coding=utf-8L=[('John',66),('Qingsword',96),('George',76),('Lifa',83)]#-------defby_name(L):"""按名称排序"""returnL[0].lower()defby_score(L):"""按分数排序"""returnL[1]print(sorted(L,key=by_name))print(sorted(L,key=by_score))#programoutput[('George',76),('约翰',66),('丽法',83),('青剑',96)][('约翰',66),('乔治',76),('丽法',83),('青剑',96)]