递归函数
递归是颇为高级的话题,它在Python中相对少见。然而,它是一项应该了解的有用的技术,因为它允许程序遍历拥有任意的、不可预知的形状的结构。递归甚至是简单循环和迭代的替换,尽管它不一定是最简单的或最高效的一种。
在每一层,这个函数都递归地调用自己来计算列表剩余的值的和,这个和随后加到前面的一项中。当列表变为空的时候,递归循环结束并返回0。当像这样使用递归的时候,对函数调用的每一个打开的层级,在运行时调用堆栈上都有自己的一个函数本地作用域的副本,也就是说,这意味着L在每个层级都是不同的。如上注释部分的print(n),可以运行查看结果。
正如你所看到的,在每个递归层级上,要加和的列表变得越来越小,直到它变为空——递归循环结束。加和随着递归调用的展开而计算出来。
例子:用递归求和
>>> def addNum(n): # 可求任意数字的和,采用递归方式实现
... if n == 1:
... return 1
... else:
... return n + addNum(n - 1)
...
>>> addNum(5)
15
>>> addNum(10)
55
>>> addNum(100)
5050
斐波拉契数列(Fibonacci),
- 公式
n(n-1) + n(n-2)
匿名函数
lambda的一般形式是关键字lambda,之后是一个或多个参数(与一个def头部内用括号括起来的参数列表极其相似),紧跟的是一个冒号,之后是一个表达式,即:
lambda para1, para2, ..…, paraN : expression using paras
由lambda表达式所返回的函数对象与由def创建并赋值后的函数对象工作起来是完全一样的,但是1ambda有一些不同之处让其在扮演特定的角色时很有用。
- lambda是一个表达式,而不是一个语句。因为这一点,lambda能够出现在Python语法不允许def出现的地方——例如,在一个列表常量中或者函数调用的参数中。此外,作为一个表达式,lambda返回了一个值(一个新的函数),可以选择性地赋值给一个变量名。相反,def语句总是得在头部将一个新的函数赋值给一个变量名,而不是将这个函数作为结果返回。
- lambda的主体是一个单个的表达式,而不是一个代码块。这个lambda的主体简单得就好像放在def主体的return语句中的代码一样。简单地将结果写成一个顺畅的表达式,而不是明确的返回。因为它仅限于表达式,lambda通常要比def功能要小:你仅能够在lambda主体中封装有限的逻辑进去,连if这样的语句都不能够使用。这是有意设计的——它限制了程序的嵌套:lambda是一个为编写简单的函数而设计的,而def用来处理更大的任务。
使用lambda表达式达到相同的效果,通过明确地将结果赋值给一个变量名,之后就能够通过这个变量调用这个函数
语法:
lambda 表达式: 语句块
>>> add = lambda x, y, z : x + y + z # 创建匿名函数
>>> print(add(1,2,3)) # 调用变量所存储的函数,传参输出
>>> 6
时间差_time模块
启动的时间
import time # 导入time模块
# 计算函数启动到结束的时间差
def bar(s): # 新建函数
time.sleep(1) # 推迟执行1秒
print(s) # 打印内容
def timeDemo():
start_time = time.time(); # 开始的时间
bar("bar() 函数启动中...") # 调用bar()函数
end_time = time.time(); # 结束的时间
print("函数启动所耗时: %s " % (end_time - start_time)) # 打印时间差
timeDemo()
高阶函数
(1):filter
- 作用
- filter的作用是过滤掉数列中不符合函数条件的元素,当数列中要删减的元素可以用某些函数描述时,可以使用
filter
函数
- filter的作用是过滤掉数列中不符合函数条件的元素,当数列中要删减的元素可以用某些函数描述时,可以使用
- 使用
variable = filter(function, sequence[str,list,tuple])
- function可以是匿名函数或者自定义函数,它会对sequence序列的每个元素判定是否符合函数条件,返回True或者False,从而只留下True的元素。
例子:求偶数、奇数等
>>> x = [1,2,3,4,5]
>>> a = filter(lambda x : x % 2 == 0, x)
>>> a # p3之后的值不再是返回列表,而是迭代器,用list转换即可
<filter object at 0x00000263FDA49240>
>>> list(a) # 返回偶数
[2,4]
------------------------
# 函数拆开
def is_even(x):
return x % 2 == 0;
# 这种拆开写的方式也可以将li遍历进函数内判断,返回值
>>> var1 = filter(is_even, li)
>>> print("函数拆开的结果:%s " % list(var1))
函数拆开的结果:[2, 4]
(2):map
- 作用
- map的作用跟filter类似,根据提供的函数对指定序列做映射,并可以进行操作。
- 使用
variable = map(function, iterable1,iterable2,...)
- function为处理序列的函数,参数可随意,iterable为有多少数值就传多少个
例子:把用户输入的名字规范化(每个名称首字母大写,其余都小写)
>>> li = [1,2,3,4,5]
>>> var2 = map(lambda x : x ** 2, li) # 平方
>>> print("原序列: %s " % li , "\n平方 => %s " % list(var2))
原序列: [1, 2, 3, 4, 5]
平方 => [1, 4, 9, 16, 25]
# 例子
>>> u_input = input("请输入:") # 第一步先获取用户输入的内容
>>> sp_str = u_input.split(' ') # 根据空格隔开
>>> def updateName(x): # 编写函数
... return x.lower().capitalize(); # 首字母大写
...
>>> res = map(updateName, sp_str) # 通过map()函数修改,传入函数和内容
>>> list(list) # 输出结果
['Made', 'In', 'China']
(3):reduce
- 作用
- 对一个序列进行压缩运算,得到一个值,但是reduce在Python2之前的时候是内置函数,到了Python3移到了functools模块,所以使用之前需要
from functools import reduce
- 对一个序列进行压缩运算,得到一个值,但是reduce在Python2之前的时候是内置函数,到了Python3移到了functools模块,所以使用之前需要
- 调用
- reduce( function,iterable)
- 其中function必须传入两个参数,iterable可以是列表或者元组
- reduce( function,iterable)
>>> from functools import reduce # 导入模块
>>> li = (11,23,4,6,7) # 创建列表
>>> var3 = reduce(lambda x, y : x + y, li) # 两个参数依次添加1和2的值,3-4,5-6,直到最后再返回
>>> print("reduce的和为: %s " % var3)
reduce的和为: 51
-----------------------------
def myAdd(x, y): # 函数单独编写
return x + y
var3 = reduce(myAdd, li) # 前两位数相加,一直到参数长度末尾
print("函数拆开结果为: %s " % var3)
函数拆开结果为: 51 # 结果也是一样
(4)apply
- 作用
- 是pandas中的函数,应用对象为pandas中的DataFrame或者Series。大致有两个方面的功能:一是直接对DataFrame或者Series应用函数,二是对pandas中的groupby之后的聚合对象apply函数
- 调用
apply( function, axis)
- function表明所使用的函数,axis表明对行、列做运算
# 导入numpy和pandas模块
>>> import numpy as np
>>> import pandas as pd
>>> tab = np.random.randint(low = 0, high = 4, size = 3, 5) # 行、列、规格: 3行5列的列表
>>> tab
array([[2, 2, 3, 3, 0],
[1, 3, 0, 2, 3],
[2, 3, 1, 1, 3]])
>>> data = pd.DataFrame(tab) # 通过变量的pd,把列表转换为表格
>>> data
0 1 2 3 4
0 2 2 3 3 0
1 1 3 0 2 3
2 2 3 1 1 3
>>> data.apply(lambda x : x * 10 ) # 通过apply函数改变行和列的值
(5)zip
-
作用
-
zip函数用于将可迭代对象作为参数,将对象中对应的元素打包成一个个元组,然后返回这些元组组成的对象。
如果迭代的元组长度不一致。则返回的对象长度为最短的那一个。
利用 * 号操作符,与zip相反,进行解压。
-
-
使用
-
zip(iterable1, iterable2,...)
- iterable:一个或多个迭代对象(str、list、tuple、dict)
Python2返回一个由元组组成的列表,Python3中返回的是一个对象,如果想要得到列表,可以用list()函数进行转换。
取值,从每一组的第一个元素开始
-
>>> li = [1,2,3,4]
>>> tup = (5,6,7,8)
>>> s = {11,23,45,2}
>>> num = zip(li, tup, s)
>>> num
<zip object at 0x000002789DE6E708>
>>> print(list(num))
[(1, 5, 2), (2, 6, 11), (3, 7, 45), (4, 8, 23)]