递归函数
递归是颇为高级的话题,它在Python中相对少见。然而,它是一项应该了解的有用的技术,因为它允许程序遍历拥有任意的、不可预知的形状的结构。递归甚至是简单循环和迭代的替换,尽管它不一定是最简单的或最高效的一种。 ![img](file:///C:\Users\ADMINI1\AppData\Local\Temp[5UQ[BL(6BS2JV6W}N6[%S.png)
https://zhidao.baidu.com/question/550718079.html
用递归求和 让我们来看一些例子。 要对一个数字列表(或者其他序列)求和,我们可以使用内置的sum函数,或者自己编写一个更加定制化的版本。这里是用递归编写的一个定制求和函数的示例:
def mysum(L):
if not L:
return 0
else:
return L[0] + mysum(L[1:]) #调用自身
print(mysum([1,2,3,4,5,6]))
第一次:L = [ 1, 2, 3, 4, 5, 6]
L[0] = 1 , l1 = L[1:] = [2, 3, 4, 5]
第二次:L = l1= [2, 3, 4, 5, 6]
L[0] = 2, L[1:] = [3, 4, 5, 6]
以此类推
在每一层,这个函数都递归地调用自己来计算列表剩余的值和
list = []
def fa(n):
if n==1:
return 1
if n==2:
return 1
else:
return fa(n-1)+fa(n-2)
for i in range(1,11):
list.append(fa(i))
print(list)
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
匿名函数
lambda表达式
lambda的一般形式是关键字lambda,之后是一个或多个参数(与一个def头部内用括号括起来的参数列表极其相似),紧跟的是一个冒号,之后是一个表达式,即:
lambda para1,para2,......,paran:expression using paras
由lambda表达式所返回的函数对象与由def创建并赋值后的函数对象工作起来是完全一样的,但是lambda有一些不同之处让其在扮演特定的角色时很有用
-
lambda是一个表达式,而不是一个语句。因为这一点,lambda能够出现在Python语法不允许def出现的地方——例如,在一个列表常量中或者函数调用的参数中。此外,作为一个表达式,lambda返回了一个值(一个新的函数),可以选择性地赋值给一个变量名。相反,def语句总是得在头部将一个新的函数赋值给一个变量名,而不是将这个函数作为结果返回。
-
lambda的主体是一个单个的表达式,而不是一个代码块。这个- lambda的主体简单得就好像放在def主体的return语句中的代码一样。简单地将结果写成一个顺畅的表达式,而不是明确的返回。因为它仅限于表达式,lambda通常要比def功能要小:你仅能够在lambda主体中封装有限的逻辑进去,连if这样的语句都不能够使用。这是有意设计的——它限制了程序的嵌套:lambda是一个为编写简单的函数而设计的,而def用来处理更大的任务。
除了这些差别,def和lambda都能够做同样种类的工作。例如:
def add(x,y,z): return x+y+z print(add(1,2,3))
使用lambda表达式到相同的效果,通过明确的将结果赋值给一个变量名,之后就能通过这个变量名来调用这个函数
num = lambda x, y, z: x+y+z print(num(2,3,4))
这里的num被赋值给一个lambda表达式创建的函数对象。这也就是def所完成的任务,只不过def的赋值是自动进行的
默认参数也就能够在lambda参数中使用,就像在def中使用一样
f= (lambda a="Tom " , b ="loves " , c="python ":a+b+c)
print(f())
print(f('liLei '))
print(f('A ','ppx ','c '))
Tom loves python
liLei loves python
A ppx c
高阶函数
高阶函数:把一个函数名,一实参的形式,传给这个函数的形参,这个函数就称为高阶函数
比如下面的形参c,对应的实参是一个函数名abs。
#函数abs()的功能是取绝对值
def add(a,b,c):
return c(a)+c(b)
add_value = add(-9,1,abs)
print(add_value)
最正确的高阶函数解释
满足下面两个条件之一,就可称之为高阶函数:
- 1、把一个函数名当做一个实参,传给另一个函数
- 2、返回值中包含函数名(不修改函数的调用方式)
实例1:
import time
def bar():
time.sleep(1)
print("函数")
def test1(func):
start_time = time.time()
func()
stop_time = time.time()
print("这个函数的运行时间是 %s"% (stop_time-start_time))
test1(bar)
函数
这个函数的运行时间是 1.0101444721221924
实例2:
import time
def bar():
time.sleep(1)
print("in the bar")
def test2(func):
print(func)
return func
bar = test2(bar)
bar()
<function bar at 0x0000012C20E21E18>
in the bar
Python中常见的高阶函数
(1)filter
- 功能
- filter的功能是过滤掉序列中不符合函数条件的元素,当序列中要删减的元素可以用某些函数描述时,就应该想起filter函数
- 调用
- filter(function,sequence)
- function可以是匿名函数或者自定义函数,它会 对后面的sequence序列的每个元素判断是否符合函数条件,返回TRUE或者FALSE,从而留下TRUE的元素;sequence可以是列表、元组或者字符串
- filter(function,sequence)
例子:
x = [1,2,3,4,5]
y = filter(lambda x: x%2==0,x) #找出偶数
print(y)
print(list(y)) #py3之后filter函数返回的不在是列表而是迭代器,所以需要用list转换
<filter object at 0x0000013CB785B0B8>
[2, 4]
普通函数使用lambda
x = [1,2,3,4,5]
def is_odd(n):
return n%2==1
print(list(filter(is_odd,x)))
[1, 3, 5]
(2)map
- 功能
- 求一个序列或者多个序列进行函数映射之后的值,就该想到map这个函数,他是python自带的函数,py3返回的是迭代器,通filter,需要进行列表转换
- 调用
- map(function,iterable1,iterable2)
- function中的参数数值不一定是一个x,也可以是x和y,甚至多个;后面的iterable表示需要参与function运算中的参数值,有几个参数值就传入几个iterable
- map(function,iterable1,iterable2)
例子:
x = [1,2,3,4,5]
y = [2,3,4,5,6]
z = map(lambda x , y : x*y + 2, x, y)
print(z)
print(list(z))
<map object at 0x00000294A2A0B1D0>
[4, 8, 14, 22, 32]
普通函数:
def f(x,y):
return x*y+2
x = [1,2,3,4,5]
y = [2,3,4,5,6]
print(list(map(f,x,y)
注:map中如果传入的几个序列的长度不一,那么会一句最短的序列进行计算
(3)reduce
-
功能
- 对一个序列进行压缩运算,得到一个值,但是reduce在python2的时候是内置函数,到了python3移到了functools模块,所以之前需要from functools import reduce。
-
调用
- reduce(function,iterable[,inital])
- 其中function必须传入两个参数,inerable可以是列表或者元组
例子:
from functools import reduce
y = [2,3,4,5,6]
z = reduce(lambda x,y: x+y, y)
print(z)
20
li = [1,2,3,4,5,6]
a=1*100000+2*10000+3*1000+4*100+5*10+6
print(a)
其计算原理:
先计算骰两个元素:f(2,3),结果为5;
再把结果和第三个元素计算:f(5,4),结果为9
再把结果和第四个元素计算:f(9,5),结果为14
再把结果和第五个元素计算:f(14,6),结果为20
由于没有更多的元素了,计算结束,返回结果为20
(4)apply
-
功能
- 是pandas中的函数,应用对象为pandas中的DataFrame或者Series。大致有两个方面的功能:一是直接对DataFrame或者Series应用函数,二是对pandas的groupby之后的聚合对象apply函数
-
调用
- apply(function.axis),function表明所使用的函数,axis表明对行或者列做运算
例子:
import numpy as np
import pandas as pd
a=np.random.randint(low=0,high=4,size=(3,5))
print(a)
data = pd.DataFrame(a)
print(data)
[[0 2 3 3 0]
[0 2 0 2 3]
[1 2 1 3 2]]
0 1 2 3 4
0 0 2 3 3 0
1 0 2 0 2 3
2 1 2 1 3 2
(5)zip
-
功能
- zip() 函数用于将可迭代对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的对象
- 如果各个可迭代对象的元素个数不一致,则返回的对象铲毒与最短的可迭代对象相同
- 利用 * 号操作符,与zip相反,进行解压
-
调用
- zip(iterable,iterable,……)
- iterable–一个或多个可迭代对象(字符串,列表,元组,字典)
- Python2中直接返回一个由元组组成的列表,Python3中返回的是一个对象,如果想要得到列表,可以用list()函数进行转换