python函数高级话题目录:

    1.递归函数

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

    2.匿名函数lambda

    3.高阶函数

    4.python中常见高阶函数

      ①.filter()

      ②.map(0

      ③.reduce()

      ④.apply()

      ⑤.zip()

      

 

 

1.递归函数

递归是颇为高级的话题,它在Python中相对少见。然而,它是一项应该了解的有用的技术,因为它允许程序遍历拥有任意的、不可预知的形状的结构。递归甚至是简单循环和迭代的替换,尽管它不一定是最简单的或最高效的一种。

用递归求和

让我们来看一些例子。

要对一个数字列表(或者其他序列)求和,我们可以使用内置的sum函数,或者自己编写一个更加定制化的版本。这里是用递归编写的一个定制求和函数的示例:

def mysum(L):
    #print(L)
    if not L:
        return 0
    else:
        return L[0]+mysum(L[1:])#调用自身
print(mysum([1,2,3,4,5,6]))

Fibonacci公式:

公式:f(x)=f(x-1)+f(x-2)

举例说明:

list=[]
n=int(input("请输入:"))#因为input输出的是str类型,所以需要强转
def sums(n):
    if n==1:
        return 1
    if n==2:
        return 1
    else:
        return sums(n-1)+sums(n-2)
for i in range(1,n+1):
    list.append(sums(i))
print(list)

在每一层,这个函数都递归地调用自己来计算列表剩余的值的和,这个和随后加到前面的一项中。当列表变为空的时候,递归循环结束并返回0。当像这样使用递归的时候,对函数调用的每一个打开的层级,在运行时调用堆栈上都有自己的一个函数本地作用域的副本,也就是说,这意味着L在每个层级都是不同的。如上注释部分的print(L),可以运行查看结果。

正如你所看到的,在每个递归层级上,要加和的列表变得越来越小,直到它变为空——递归循环结束。加和随着递归调用的展开而计算出来。

 

 

2.匿名函数lambda

lambda表达式

lambda的一般形式是关键字lambda,之后是一个或多个参数(与一个def头部内用括号括起来的参数列表极其相似),紧跟的是一个冒号,之后是一个表达式,即:

lambda para1, para2, ..…, paraN : expression using paras

由lambda表达式所返回的函数对象与由def创建并赋值后的函数对象工作起来是完全一样的,但是1ambda有一些不同之处让其在扮演特定的角色时很有用。

  1、lambda是一个表达式,而不是一个语句。因为这一点,lambda能够出现在Python语法不允许def出现的地方——例如,在一个列表常量中或者函数调用的参数中。此外,作为一个表达式,lambda返回了一个值(一个新的函数),可以选择性地赋值给一个变量名。相反,def语句总是得在头部将一个新的函数赋值给一个变量名,而不是将这个函数作为结果返回。

  2、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))
#结果:6

利用lambda写的例子:

sm = lambda x,y,z : x+y+z
print(sm(1,2,3),type(sm))  
# 结果6    <class 'function'>

这里的sm被赋值给一个lambda表达式创建的函数对象,这里就是def所完成的任务,只不过def的赋值是自动进行的。

默认参数也能够在lambda参数中使用,就像在def中使用一样。

f=(lambda a='zs',b='ls',c='ww':a+b+c)
print(f())
print(f('tom'))
print(f('tom','love','zhangsan'))

以上运行结果:

zslsww
tomlsww
tomlovezhangsan

 

 

3.高阶函数

高阶函数:把一个函数名,以实参的形式,传给这个函数的形参,这个函数就称为高阶函数。

比如下面的形参c,对应的实参是一个函数abs对象.

def add(a,b,c):
    return c(a)+c(b)
add_value=add(-9,1,abs)    # 传入abs函数对象
print(add_value)
#运行结果:10

最正确的高阶函数解释
满足下面两个条件之一,就可称之为高阶函数:

    • 1.把一个函数名当做一个实参,传给另外一个函数

    • 2.返回值中包含函数名(不修改函数的调用方式)

示例1:

import time     # 导入时间模块
def bar():
    time.sleep(1)    # 睡眠1秒钟
    print("函数bar")

def test1(func):#高阶函数(满足了条件)
    start_time=time.time()    # 函数执行前时间戳
    func()    #    执行bar()函数,睡眠1秒钟
    stop_time=time.time()     # 执行函数完时间戳
    print("这个函数的运行时间是%s"%(stop_time-start_time))   # 时间差
test1(bar)
# 以下结果
# 睡眠一秒钟
# 函数bar
# 这个函数的运行时间是1.0007131099700928

示例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 0x0000021FC3C71E18>
#         in the bar

 

 

4.Python中常见的高阶函数

(1)filter

功能

  filter的功能是过滤掉序列中不符合函数条件的元素,当序列中要删减的元素可以用某些函数描述时,就应该想起filter函数

调用: 

  filter(function,sequence),function是条件,sequence是序列
    function可以是匿名函数或者自定义函数,它会对后面的sequence序列的每个元素判定是否符合函数条件,返回TRUE或者FALSE,从而只留下TRUE的元素;sequence可以是列表,元组或者字符串。

例子1:

x=[1,2,3,4,5]
y=filter(lambda x:x%2==0,x)#找出偶数
print(y)
#结果:<filter object at 0x000002B97F1F7128>    #过滤后的对象
print(list(y))#py3之后filter函数返回的不再是列表而是迭代器,所以需要用list转换
#结果:[2, 4]

例子2:

#普通函数
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

例子1:

x=[1,2,3,4,5]
y=[2,3,4,5,6]
z=map(lambda x,y:(x*y)+2,x,y)
print(z)
#结果:<map object at 0x000001594F007198>
print(list(z))
#结果:[4, 8, 14, 22, 32]

例子2:

#普通函数:
def func(x,y):
    return x*y+2
x=[1,2,3,4,5]
y=[2,3,4,5,6]  
print(list(map(func,x,y)))
#结果:[4, 8, 14, 22, 32]

例子3:

#传入3参数也是一样的
def func(x,y,z):
    return x*y+z
x=[1,2,3,4,5]
z=y=[2,3,4,5,6]  
print(list(map(func,x,y,z)))

注:map中如果传入的几个序列的长度不一,那么会依据最短的序列进行计算

 

(3)reduce

功能:

  • 对一个序列进行压缩运算,得到一个值,但是reduce在python2的时候是内置函数,到了python3移到了functools模块,所以使用之前需要 from functools import reduce

调用:

  • reduce(function ,iterable)
  • 其中function必须传入两个参数,iterable可以是列表或者元组

例子1:

from functools import reduce
y=[2,3,4,5,6]
z=reduce(lambda x,y:x+y,y)
print(z)
#结果:20

例子2:

#普通函数:
from functools import reduce
def tools(x,y):
    return x+y
y=[2,3,4,5,6]
print(reduce(tools,y,100))

其计算原理:

先计算头两个元素:f(2, 3),结果为5;

再把结果和第3个元素计算:f(5, 4),结果为9;

再把结果和第4个元素计算:f(9, 5),结果为14;

再把结果和第5个元素计算:f(14, 6),结果为20;

由于没有更多的元素了,计算结束,返回结果20。

 

(4)apply

功能:

  • 是pandas中的函数,应用对象为pandas中的DataFrame或者Series.大致有两个方面的功能:一是直接对DataFrame或者Series应用函数,二是对pandas中的groupby之后的聚合对象apply函数

调用:

  apply(function,axis),function表明所使用的函数,axis表明对行或者列做运算。

  安装才能使用apply函数

#在cmd命令窗口安装
pip install numpy
pip install pandas
#画图
pip install matplotlib
画图使用先导包:
import matplotlib.pyplot as plt
>>> x=[4,7,11,21]
>>> plt.plot(x)
[<matplotlib.lines.Line2D object at 0x000001F66180BDD8>]
>>> plt.show()
>>>

例子:

>>> import numpy as np
>>> import pandas as pd
>>> a=np.random.randint(low=0,high=4,size=(2,4))
>>> a
array([[0, 2, 2, 0],
       [1, 2, 2, 1]])
>>> data=pd.DataFrame(a)
>>> data
   0  1  2  3
0  0  2  2  0
1  1  2  2  1
>>> data.apply(lambda x:x*10)
    0   1   2   3
0   0  20  20   0
1  10  20  20  10
>>>

 

(5)zip

功能:

  zip()函数用于将可迭代对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的对象。

  如果各个可迭代对象的元素个数不一致,则返回的对象长度与最短的可迭代对象相同。

  利用*号操作符,与zip相反,进行解压。

调用:

  • zip(iterable1,iterable2,…)

  • iterable 一个或多个可迭代对象(字符串、列表、元组、字典)

    python2中直接返回一个由元组组成的列表,python3中返回的是一个对象,如果想要得到列表,可以用list()函数进行转换。​

例子1:

x=[2,3,4,5,6]
y=[4,5,6,7,8]
print(list(zip(x,y)))
#结果:[(2, 4), (3, 5), (4, 6), (5, 7), (6, 8)]

例子2:

a=[1,2,3]#此处可迭代对象为列表
b=[4,5,6]
c=[5,6,7,8,9]
zipTest=zip(a,b)
# <zip object at 0x00000115C0C87288>返回的是一个对象
print(zipTest)
print(list(zipTest))#转为列表
#结果:[(1, 4), (2, 5), (3, 6)]
zipT=zip(a,c)
print(list(zip(*zipT)))#解压也使用list进行转换
#结果:[(1, 2, 3), (5, 6, 7)]

例子3:

a = {1: 11, 2: 22}  # 此处可迭代对象为字典
b = {3: 33, 4: 44}
c = {5: 55, 6: 66, 7: 77}
ziptest = zip(a, b, c)
print(list(ziptest))  # [(1, 3, 5), (2, 4, 6)]
zipt = zip(a, b)
print(list(zip(*zipt)))     # [(1, 2), (3, 4)]

题目:

1.利使用map()函数,把使用户输入的不规范的英文名字,变为首字母大写,其余小写的规范名字。输入:[hunan, YINGXIAO, COllege],输出:[Hunan, Yingxiao, College]
2.回文数是指从左向右读和从右向左读都是一样的数,例如12321,909。请利使用filter()挑选出1-1000里的回文数:
python函数-高级话题 随笔 第1张
①.第一题
def formatation(seq):
    return seq[0].upper()+seq[1:].lower()
sr=['hunan','CHANGSHA','collage']
print(list(map(formatation,sr)))

#运行结果:
#['Hunan', 'Changsha', 'Collage']

②.第二题
def palindrome(n):
    rev_n=int(str(n)[::-1])    # 将字符串反转
    if rev_n==n:
        return rev_n
print(list(filter(palindrome,range(1,1000))))
#运行结果:[1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, 44, 55, 66, 77, 88, 99, 101, 111, 121, 131, 141, 151, 161, 171, 181, 191, 202, 212, 222, 232, 242, 252, 262, 272, 282, 292, 303, 313, 323, 333, 343, 353, 363, 373, 383, 393, 404, 414, 424, 434, 444, 454, 464, 474, 484, 494, 505, 515, 525, 535, 545, 555, 565, 575, 585, 595, 606, 616, 626, 636, 646, 656, 666, 676, 686, 696, 707, 717, 727, 737, 747, 757, 767, 777, 787, 797, 808, 818, 828, 838, 848, 858, 868, 878, 888, 898, 909, 919, 929, 939, 949, 959, 969, 979, 989, 999]
解析

 

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄