Day16 函数式编程与内置函数

函数作用域

1.作用域即范围

  • 全局范围(内置名称空间与全局名称空间属于该范围):全局存活,全局有效  
  • 局部范围(局部名称空间属于该范围):临时存活,局部有效

2.作用域关系是在函数定义阶段就已经固定的,与函数的调用位置无关

3.查看作用域,LEGB 代表名字查找顺序: locals -> enclosing function -> globals -> __builtins__

  • locals 是函数内的名字空间,包括局部变量和形参
  • enclosing 外部嵌套函数的名字空间(闭包中常见)
  • globals 全局变量,函数定义所在模块的名字空间
  • builtins 内置模块的名字空间

一、匿名函数

匿名函数关键字 形参:(处理逻辑)返回值

lambda argument_list: expression

调用方法(不应该这么使用):

func = lambda x:x+1

func(x)

在需要返回多个值的时候,需要自己加上括号变成元组,因为函数中的return会自动把返回值变成元组形式

一般情况下,不适用Lambda函数,而是将其与高阶函数一起使用(如python内置的高阶函数Map, Reduce等)。

假设有一个整数列表,必须返回三个输出。

  • 一个列表中所有偶数的和
  • 一个列表中所有奇数的和
  • 一个所有能被三整除的数的和

首先假设用普通函数来处理这个问题。在这种情况下,将声明三个不同的变量来存储各个任务,并使用一个for循环处理并返回结果三个变量。该方法常规可正常运行。

现在使用Lambda函数来解决这个问题,那么可以用三个不同的Lambda函数来检查一个待检验数是否是偶数,奇数,还是能被三整除,然后在结果中加上一个数。

def return_sum(func, lst):
  result = 0
  for i in lst:
    #if val satisfies func
    if func(i):
      result = result + i
  return result
lst = [11,14,21,56,78,45,29,28]
x = lambda a: a%2 == 0
y = lambda a: a%2 != 0
z = lambda a: a%3 == 0
print(return_sum(x, lst))
print(return_sum(y, lst))
print(return_sum(z, lst))

# 输出
176
106
144

二、函数式编程

编程的方法论:

  • 面向过程:找到解决问题的入口,按照一个固定的流程去模拟解决问题的流程
  • 函数式:用编程语言去实现数学函数,所有循环都由递归去实现,无变量的赋值
  • 面向对象

函数式编程

高阶函数

  • 把函数当作参数传给另一个函数(也可以把自己作为返回值)
  • 返回值中包含函数
def test():
    print('Test 1')
    return test()

def example():
    print('Example 1')
    return example

# t = test()		# 死循环,不断执行test
e = example()       # 返回函数地址
e()

# 输出
Example 1
Example 1

尾调用(尾递归优化):在函数执行的最后一步执行另一个函数

在A函数调用时会将A函数放入调用栈中,如果在A函数中存在另一个函数B调用,此时也会将B压入调用栈中,等待函数B调用完成后,此时才可以从调用栈中弹出函数A和函数B。那如果使用尾调用时,当执行函数A时,将函数A压入调用栈中,当执行A时发现存在函数B,并且函数B为函数A的最后一步调用,此时可以将函数A从调用栈中弹出,将函数B压入调用栈中。这样下来性能就做到了优化。

尾递归:如果尾调用自身则称为尾递归。

递归非常消耗内存,因为需要同时保存成千上万个调用记录,很容易发生栈溢出的错误。但是对于尾递归来说,由于只存在一个调用记录,所以永远不会发生栈溢出。同时可以对函数中的某些参数使用默认值,这样当我们没有输入该参数时,就会使用默认值

map函数:map(处理方法,可迭代对象)

处理方法可以是lambda匿名函数也可以是定义函数

处理序列中的每个元素,得到一个‘列表’,该‘列表’元素个数及位置与原来一样

【迭代可迭代对象中的每个元素进行相应的转换操作】

before = [1,2,3]

after = list(map(lambda x:x*2, before))

# after is [2,4,6]

 

 

filter函数:filter(处理方法,可迭代对象)

处理方法可以是lambda匿名函数也可以是定义函数

遍历序列中的每个元素,判断每个元素得到布尔值,如果是True则留下来

【用于可迭代,仅保留满足特定条件的某些元素】

before = [1,2,3,4,5,6]

after = list(filter(lambda x:x%2==1, before))

# after is [1,3,5]

 

reduce函数:reduce(处理方法,可迭代对象,init)

处理方法可以是lambda匿名函数也可以是定义函数

【lambda函数需要两个参数,用于将两个元素组合起来】

处理一个序列,然后把序列进行合并操作

【以某种方式在组合可迭代对象中的所有元素】

from functools import reduce    #现在必须从模块中引入reduce

before = [1,2,3,4,5]

after = reduce(lambda a,b: a*b, before)

# after is 120

 

三、常见内置函数

内置函数功能
abs()返回绝对值
all()如果可迭代对象中每个元素都为True则返回True
any()如果可迭代对象中有任何一个元素为True则返回True
bin()将整数转换为二进制数
hex()将整数转换为十六进制数
oct()将整数转换为八进制数
bool()判断对象是否为真
bytes()将对象转换为二进制格式
chr()将ASCII码转换为字符
ord()将字符转换为ASCII码
dir()打印对象中存在的方法和属性
divmod()返回整除和取模的结果
eval()执行字符串中的表达式并返回结果
hash()对对象进行哈希运算
isinstance()判断对象是否为指定类的实例
globals()返回全局变量的字典
locals()返回局部作用域的字典
max()返回可迭代对象中的最大值
min()返回可迭代对象中的最小值

max()min()方法

1.处理得是可迭代对象,相当于一个for循环取出每个元素进行比较,但不同类型之间不可以相互比较;

2.每个元素间进行比较,是从每个元素的第一个位置依次比较,如果这一个位置分出大小,后面就不需要比较了,直接得出两个元素大小

dic = {'age1':18, 'age2':20, 'age3':152}

print(list(max(zip(dic.values(), dic.keys()))))

# 输出
[152, 'age3']

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

如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作符,可以将元组解压为列表。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值