递归函数、纯函数、匿名函数lambda、常用内置函数

递归函数
  在函数中调用函数自身;递归函数一定要写终止条件,否则将产生无限递归即死循环。

# 阶乘 6*5*4*3*2*1

def func(n):
    if n == 1:
        return 1
    else:
        return n * func(n - 1)  # 累加把*换成+即可


print(func(6))  # 6*5*4*3*2*1 = 720

import sys

# 获取最大递归深度
res = sys.getrecursionlimit()
print(res)  # 1000
# 可以通过setrecursionlimit去设置递归最大深度
# 但是要考虑内存能否满足条件,内存满了就会停止,一般不会修改这个
# sys.setrecursionlimit(5000)

# Python中递归效率比较低,不推荐使用递归
# 每次调用函数都需要临时开辟一块内存去保存函数运行中的数据,无论函数是否相同的参数去重复调用
# 直到递归全部运行完毕才去释放内存
# 针对这种情况可以使用 缓存装饰器 去提升递归函数的运行效率
# 优化运行机制,把调用函数对于相同参数重复调用的,无需重新函数计算(无须新开辟内存),直接返回之前缓存的返回值
# 如果必须使用递归函数去解决问题时,可以结合实际情况选择使用缓存装饰器,来大大提高运行效率

from functools import lru_cache


@lru_cache(maxsize=128)  # maxsize参数指调用时递归占多少内存
def func_lru(n):
    if n == 1 or n == 2 or n == 3:
        return n
    else:
        return func(n - 1) + func(n - 2) + func(n - 3)


func_lru(50)

斐波那契数列指的是这样一个数列0,1,1,2,3,5,8,13,21,34...这个数列从第3项开始,每一项都等于前两项之和

def fei(x):
    if x <= 0:
        return '无'
    elif x == 1 or x == 2:
        return 1
    else:
        return fei(x - 1) + fei(x - 2)

纯函数
  函数的返回结果只依赖于它的参数,并且在执行过程中没有副作用。
三个原则
  1、变量都只在函数作用域内获取,或者作为函数的参数传入
  2、相同的输入保证相同的输出
  3、不会产生副作用,不会改变被传入的数据或者全局变量的其他数据
函数的副作用
  访问了函数外的数据,对外部数据进行了操作改变了系统环境
纯函数的作用就是降低代码的耦合度(代码的耦合度,是指代码中的单元代码的紧密程度,其中一个单元代码的更改对其它单元代码的影响力与作用)

# 纯函数
def func(a, b):
    return a + b

# 不是纯函数,使用了外部变量
c = 100
def func1(a, b):
    return a + b + c

# 不是纯函数,调用函数后就改变了外部数据
li = []
def func2(a, b):
    li.append(a)
    li.append(b)
    return a + b

匿名函数(lambda 表达式)
  语法  lambda 参数: 返回值
  用来定义一些比较简单,不会重复使用的函数,通常结合内置函数filter(过滤器函数,传参第一个要传函数或者None,第二个参数要传可迭代对象)使用(这种即为函数当做参数使用);用完即销毁,释放内存。

def fun(a, b):  # 普通函数
    return a + b

# 等同于上面的fun()函数;冒号之前的a,b 代表传入的参数;冒号之后的a+b代表返回值
f = lambda a, b: a + b
print(f(11, 22))  # 33
# 匿名函数另一种写法,后面(22,33)代表直接传参,很少使用这种
res = (lambda a, b: a + b)(22, 33)
print(res)  # 55

lis = [1, 2, 3, 4, 5, 6, 7, 8]
# lis可迭代对象,在此处相当于for循环去赋值给前面的x,判断x>3为True就过滤出来,如果不成立就不要这个数据
res = filter(lambda x: x > 3, lis)
print(res)  # <filter object at 0x0000029EF2398FA0> 过滤器对象
print(list(res))  # [4, 5, 6, 7, 8]
# filter(lambda x: x > 3, lis) 可以解释为以下两行代码
# for i in lis:
#     res1 = (lambda x: x > 3)(i)

# 还可以结合or或者三目运算符处理一些简单的逻辑
res1 = lambda x: x * 10 or 5
print(res1(0))  # 5
res2 = lambda x: x * 10 if x > 5 else x * 2
print(res2(6))  # 60 if条件成立就执行if之前的语句
print(res2(4))  # 8  不成立就执行else之后的语句

常用内置函数
  abs() 获取绝对值
  all() 传入一个可迭代对象,迭代对象内所有元素为真,返回True
  any() 传入一个可迭代对象,迭代对象内只要有一个元素,返回True
  map() 传入一个函数和一个或多个可迭代对象,会根据提供的函数对指定序列做映射,返回的是迭代器
  zip() 聚合打包,会把每个可迭代对象内索引位置相同的聚合在一起,返回的是迭代器,可以使用list()生成列表,传入两个可迭代对象时可以使用dict()转为字典,前提是k值为不可变数据类型

print(abs(-99))  # 99 获取绝对值
a = 1
b = 2
c = 3
print(all([a, b, c]))  # True 可以代替 if a and b and c
print(any([a, b, c]))  # True 可以代替 if a or b or c
print(map(float, [1, 2, 3, 4]))  # <map object at 0x000001B30E5AEAF0>
print(list(map(float, [1, 2, 3, 4])))  # [1.0, 2.0, 3.0, 4.0] 把列表内数据转成float类型
# [3, 7, 11, 15, 19] 提供了两个列表,对相同位置的列表数据进行相加
print(list(map(lambda x, y: x + y, [1, 3, 5, 7, 9], [2, 4, 6, 8, 10])))

def square(x):  # 计算平方数
    return x ** 2

map(square, [1, 2, 3, 4, 5])  # 计算列表各个元素的平方,返回迭代器<map object at 0x0000020BBF26E970>
print(list(map(square, [1, 2, 3, 4, 5])))  # [1, 4, 9, 16, 25],使用 list() 转换为列表 

print(list(map(lambda x: x ** 2, [1, 2, 3, 4, 5])))  # [1, 4, 9, 16, 25],使用 lambda 匿名函数

aa = [1, 2, 3]
bb = ['a', 'b', 'c']
cc = [11, 22, 33, 44]
print(zip(aa, bb))  # <zip object at 0x0000018D0F8C7D00>
print(next(zip(aa, bb)))  # (1, 'a')
print(dict(zip(aa, bb)))  # {1: 'a', 2: 'b', 3: 'c'}
print(list(zip(aa, bb, cc)))  # [(1, 'a', 11), (2, 'b', 22), (3, 'c', 33)]
li1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
# 把li1列表处理成[[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12], [13, 14, 15]]
# 方式一、使用推导式+列表切片,设置步长为3
li2 = [li1[i:i + 3] for i in range(0, len(li1), 3)]
# 方式二、使用推导式+zip
li3 = [list(i) for i in list(zip(li1[0:len(li1):3], li1[1:len(li1):3], li1[2:len(li1):3]))]
# 方式三、zip+lambda+map
li4 = list(map(lambda x: list(x), zip(li1[0:len(li1):3], li1[1:len(li1):3], li1[2:len(li1):3])))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值