内部函数

Python中函数的作用域由def关键字界定,函数内的代码访问变量的方式是从其所在层级由内向外,若往外直至全局作用域都查找不到的话代码会抛异常。

主要看以下代码的差别~~

  """def f1():x = 5def f2():x *= xreturn xreturn f2"""def f1():x = [5]def f2():x[0] *= x[0]return x[0]return f2()print(f1())def f1():x = [5]def f2():x[0] *= x[0]return x[0]return f2print(f1()())def f1():x = 5def f2():nonlocal xx *= xreturn xreturn f2print(f1()())

闭包 closure

  • 闭包的一些定义

    • 闭包的定义:闭包是由函数及其相关的引用环境组合而成的实体(即:闭包=函数+引用环境)。

    • python中闭包的定义:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure)

    • 闭包函数的必要条件:

      • 闭包函数必须返回一个函数对象
      • 闭包函数返回的那个函数必须引用外部变量(一般不能是全局变量),而返回的那个函数内部不一定要return
      • 闭包函数引用的外部变量不一定就是其父函数的参数,也可以是父函数作用域内的任意变量

      下面三个例子为常见的闭包

        # NO.1def line_conf(a, b):def line(x):return a * x + breturn line# NO.2def line_conf():a = 1b = 2def line(x):print(a * x + b)return line# NO.3def _line_(a, b):def line_c(c):def line(x):return a * (x ** 2) + b * x + creturn linereturn line_c
  • 为何称作闭包
    按照命令式语言的规则,ExFunc函数只是返回了内嵌函数InsFunc的地址,在执行InsFunc函数时将会由于在其作用域内找不到sum变量而出 错。而在函数式语言中,当内嵌函数体内引用到体外的变量时,将会把定义时涉及到的引用环境和函数体打包成一个整体(闭包)返回。
    以下列子:

      def line_conf(a):b=1def line(x):return a * x + breturn lineline_A = line_conf(2)b=20print(line_A(1))  # 3
    
    • line_A对象作为line_conf返回的闭包对象,它引用了line_conf下的变量b=1,在print时,全局作用域下定义了新的b变量指向20,最终结果仍然引用的line_conf内的b。这是因为,闭包作为对象被返回时,它的引用变量就已经确定(已经保存在它的__closure__属性中),不会再被修改。
    • 即闭包函数被当作变量返回时,它的所有变量就已经固定,形成了一个封闭的对象,这个对象包含了其引用的所有外部、内部变量和表达式。当然,闭包的参数例外。
  • 显式查看闭包
    __closure__属性返回的是一个元组对象,包含了闭包引用的外部变量。
    根据NO.1,可以使用一些代码查看闭包信息:

      L = line_conf()print(line_conf().__closure__) #(<cell at 0x05BE3530: int object at 0x1DA2D1D0>,for i in line_conf().__closure__: print(i.cell_contents)  # 打印引用的外部变量值,为1, 2
    
  • 闭包的作用
    闭包最主要的作用是提高代码的可复用性,根据NO.1,输出两条直线:

      #定义两条直线line_A = line_conf(2, 1) #y=2x+bline_B = line_conf(3, 2) #y=3x+2#打印x对应y的值print(line_A(1)) #3print(line_B(1)) #5# 不使用闭包的代码def line_A(x):return 2*x+1def line_B(x):return 3*x+2print(line_A(1)) #3print(line_B(1)) #5
    

    两条直线看不出区别,当需要定义几十几百条,闭包优势就出来了。

  • 闭包的实际运用

    • 例子1:

        def who(name):def do(what):print(name, 'say:', what)return dolucy = who('lucy')john = who('john')lucy('i want drink!')lucy('i want eat !')lucy('i want play !')john('i want play basketball')john('i want to sleep with U,do U?')lucy("you just like a fool, but i got you!")
      

匿名函数 lambda

  • 特性
    使用lambda可以精简代码、不需要考虑重名函数、可读性,lambda argument_list: expression,特性如下:

    • lambda函数是匿名的:所谓匿名函数,通俗地说就是没有名字的函数。lambda函数没有名字;
    • lambda函数有输入和输出:输入是传入到参数列表argument_list的值,输出是根据表达式expression计算得到的值
    • lambda函数一般功能简单:单行expression决定了lambda函数不可能完成复杂的逻辑,只能完成非常简单的功能。(不支持if else等逻辑判断)
  • 示例:
    • lambda x, y: xy;函数输入是x和y,输出是它们的积xy
    • lambda:None;函数没有输入参数,输出是None
    • lambda *args: sum(args); 输入是任意个数的参数,输出是它们的和(隐性要求是输入参数必须能够进行加法运算)
    • lambda **kwargs: 1;输入是任意键值对参数,输出是1

映射map/reduce

  • map

    • 功能: 求一个序列或者多个序列进行函数映射之后的值,就该想到map这个函数,它是python自带的函数,在python3.*之后返回的是迭代器,同filter,需要进行列表转换
    • 调用: map(function,iterable1,iterable2),function中的参数值不一定是一个x,也可以是x和y,甚至多个;后面的iterable表示需要参与function运算中的参数值,有几个参数值就传入几个iterable
    • 实例:
      x = [1,2,3,4,5]y = [2,3,4,5,6]list(map(lambda x,y:(x*y)+2,x,y))# 输出:[4, 8, 14, 22, 32]
    
  • reduce
    从python 3 开始移到了 functools 模块

    • reduce()函数接收的参数和 map()类似,一个函数 f,一个list,但行为和 map()不同,reduce()传入的函数 f 必须接收两个参数,reduce()对list的每个元素反复调用函数f,并返回最终结果值。
    • reduce()还可以接收第3个可选参数,作为计算的初始值
def f(x, y):return x + yreduce(f, [1, 3, 5, 7, 9])  # 25reduce(f, [1, 3, 5, 7, 9], 100)  # 125,计算初始值和第一个元素:f(100, 1),结果为101

过滤器 filter

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

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

  • 实例:

      x = [1,2,3,4,5]list(filter(lambda x:x%2==0,x)) # 找出偶数。python3.*之后filter函数返回的不再是列表而是迭代器,所以需要用list转换。# 输出:[2, 4]
    

sorted、sort

  • 基本
    前面也说有高阶函数:map/reduce、filter。sorted()也是一个高阶函数。用sorted()排序的关键在于实现一个映射函数。
  • 默认是升序排序,可用:reverse=True 实现倒叙排序。
  • 默认情况下,对字符串排序,是按照ASCII的大小比较的,由于’Z’ < ‘a’,结果,大写字母Z会排在小写字母a的前面。可用:key=str.lower 忽略首字母的大小写。
  • sorted和sort

    • sort方法是列表类型list的内置方法,使用sort方法对list排序会修改list本身,不会返回新的list,sort方法只能用于列表,不能对字典、元祖等其他可迭代对象进行排序。
      list.sort( key=None, reverse=False)
    • sorted() 函数能对所有可迭代的对象进行排序操作,sorted()函数不会改变原来的对象,而是会返回一个新的已经排序好的对象。
      sorted(iterable, key=None, reverse=False)
  • 排序与lambda
    lambda可用实现字典key或者是value的排序,又或者是JSON格式的排序。样例如代码:
list = [2, 5, -4, 11, 7]
print(list.sort())
print(list)
print(sorted(list, reverse=True))dict = {'a':2,'E':3,'f':8,'d':4}
print(sorted(dict))
print(sorted(dict, reverse=True))
print(sorted(dict, reverse=True, key=str.lower))
print(sorted(dict.items(), key=lambda x : x[1]))array = [{"age":20,"name":"a"},{"age":25,"name":"b"},{"age":10,"name":"c"}]
array = sorted(array,key=lambda x:x["age"], reverse=False)
print(array)

偏函数

functools模块提供有wrap与偏函数,可以设定参数的默认值,降低函数的调用难度。

例如,我们有个需求,需要将二进制转为int,那应该是:

int(‘100000101’, base=2) # 261

每次转换都这样,比较麻烦,于是写了函数int2

def int2(num, base=2):return int(num, base)

使用functools.partial就是帮助创建一个这样的偏函数,不用自己定义int2()

import functoolsint2 = functools.partial(int, base=2)
int2('101010110')

创建偏函数时,实际上可以接受 函数对象、*args、**kw 这三个参数,以上例子实际上固定了int()函数的关键参数base,也就是:
int2(‘101010110’)
相当于:
kw = {‘base’, 2}
int(‘101010110’, **kw)
当传入:
max2 = functools.partial(max, 10)
实际上会将10作为 *args 的一部分自动加到左边,也就是:
max2(4, 9) 相当于: max2(10, 4, 9)
偏函数用于固定住原函数的部分参数,使得调用更简单。

个人博客:Loak 正 - 关注人工智能及互联网的个人博客
文章地址:Python基础(六)—函数式编程(内部函数、闭包、lambda、filter/map/reduce/sorce、偏函数)

Python基础(六)—函数式编程(内部函数、闭包、lambda、filter/map/reduce/sorce、偏函数)相关推荐

  1. Python进阶:函数式编程(高阶函数,map,reduce,filter,sorted,返回函数,匿名函数,偏函数)...啊啊啊...

    函数式编程 函数是Python内建支持的一种封装,我们通过把大段代码拆成函数,通过一层一层的函数调用,就可以把复杂任务分解成简单的任务,这种分解可以称之为面向过程的程序设计.函数就是面向过程的程序设计 ...

  2. py函数式编程(高阶函数map/reduce/filter/sorted、闭包函数/返回函数、匿名函数lamber、@装饰器decorator、偏函数functool.partial())

    #py函数式编程.py #高阶函数map/reduce/filter/sorted.闭包函数/返回函数.匿名函数lamber.@装饰器decorator.偏函数functool.partial()# ...

  3. Python高级特性: 函数编程 lambda, filter,map,reduce

    一.概述 Python是一门多范式的编程语言,它同时支持过程式.面向对象和函数式的编程范式.因此,在Python中提供了很多符合 函数式编程 风格的特性和工具. 以下是对 Python中的函数式编程 ...

  4. python3函数中lambda/filter/map/reduce的用法

    lambda/filter/map/reduce这几个函数面试中很肯定会用到,本篇主要介绍这几个函数的用法. 1.lambda 匿名函数,用法如下: # lambada 参数,参数,参数 : 返回的表 ...

  5. 函数式编程是啥玩意?map() reduce()(reduce()函数将数字列表转换为x进制数字)闭包、装饰器、偏函数

    反正看了百度百科的介绍我是没太看懂... 参考文章:函数式编程 看了这篇,不错,对python函数式编程有些许理解了: 变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数 ...

  6. C#函数式编程风格-范型Filter,Map,Reduct函数的实现

    早上看园友的一篇文章<lambda与闭包>,忽然间想起了以前刚学Python,刚接触FP时的高兴劲.对FP的no-side-effect的向往,对Declaration式编程的喜爱,让我对 ...

  7. python基础(part17)--函数式编程

    鄙人学习笔记 开发工具:Spyder 文章目录 函数式编程 举个例子1 举个例子2 举个例子3 函数作为参数 lambda表达式 举个例子1 内置高阶函数 filter map sorted max ...

  8. [Python] 函数lambda(), filter(), map(), reduce()

    转载地址:http://blog.csdn.net/dbanote/article/details/8912250 1.lambda() lambda()是Python里的匿名函数,其语法如下: la ...

  9. 五分钟学会python函数_Python——带你五分钟了解函数式编程与闭包

    今天是Python专题的第9篇文章,咱们来聊聊Python的函数式编程与闭包.编程 函数式编程 函数式编程这个概念咱们可能或多或少都据说过,刚据说的时候不明觉厉,以为这是一个很是黑科技的概念.可是实际 ...

最新文章

  1. 打包caddy为docker镜像
  2. 远程连接CentOS的MySQL报错:Can't connect to MySQL server on 'XXX' (13)
  3. 2020年快手校招JAVA岗笔试第二题
  4. 高并发分布式系统中生成全局唯一(订单号)Id
  5. Jmeter笔记(Ⅱ)使用Jmeter实现轻量级的接口自动化测试
  6. 话说这发表日志跟聊天似的简单很啊。
  7. 为什么俺推荐Python「1」:作为脚本语言的Python
  8. 三年经验前端开发面试总结
  9. 世界五百强面试题计算机,世界五百强IT企业最新C++经典面试题及答案
  10. Vue将HTML内容用打印机打印出来
  11. Saas.为什么要搞Saas,会遇到哪些问题,看看5年Saas开发踩过的坑
  12. 搜狗输入法中文状态下开启和关闭英文自动提示
  13. python 反余弦函数_Python
  14. 移植mysql到安卓手机_记录dbnet文本检测转ncnn并移植到安卓上
  15. 天星数科首页CSS布局回顾
  16. 输入一个整数判断其是否是回文数
  17. 【蓝桥杯单片机(24)】历届单片机客观题及答案解析
  18. 第七次全国人口普查公报[1](第八号) ——接受普查登记的港澳台居民和外籍人员情况
  19. 那些年、那些人、那些事(iprouter迟到三年的JNCIP回忆录)
  20. 人生的十种意境!!!

热门文章

  1. 百度艾菲达成深度合作 引领AI营销新实践
  2. android 画布 轨迹,Android 多点触控,绘制滑动轨迹和十字光标
  3. 【英语:基础进阶_语法进阶提升】F3.被动语态
  4. Logit Adjust
  5. R语言小代码6(股票数据分析)
  6. WakeData完成1000万美元B轮融资,红点中国、红杉中国联合领投
  7. 什么是计算机电源线,电脑电源线接法是什么?(电脑电源线接法的相关内容)...
  8. 媒体笔记第1篇:“四全媒体”释义
  9. TCP通讯程序的编写
  10. 杭州为什么能办一个区块链周