高阶函数

话说当年C语言和Java里好像都有这么个东西...忘了

一句话说就是函数名本身就是一个引用. 可以作为变量传递.

一个简单的例子:

  1. def power_demo(x): 


  2. return x*x 



  3. def foo(num1,num2,fun): 


  4. return fun(num1) + fun(num2) 



  5. print(foo(2,3,power_demo)) 



map/reduce的用法

map()方法

map(function, iterable, ...)

Return an iterator that applies function to every item of iterable, yielding the results. If additional iterable arguments are passed, function must take that many arguments and is applied to the items from all iterables in parallel. With multiple iterables, the iterator stops when the shortest iterable is exhausted. For cases where the function inputs are already arranged into argument tuples, see itertools.starmap().

解读:

入参是一个函数和一个可迭代对象. 函数依次作用于可迭代对象上.

返回值是一个迭代器

  1. def f(x): 


  2. return x*x 


  3. L = map(f,[1,2,3,4,5,6]) 


  4. print(type(L)) 


  5. print(list(L)) 



reduce()方法

functools.reduce(function, iterable[, initializer])

Apply function of two arguments cumulatively to the items of sequence, from left to right, so as to reduce the sequence to a single value.

For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates ((((1+2)+3)+4)+5).

The left argument, x, is the accumulated value and the right argument, y, is the update value from the sequence. If the optional initializer is present, it is placed before the items of the sequence in the calculation, and serves as a default when the sequence is empty. If initializer is not given and sequence contains only one item, the first item is returned.

文档中给出的大概的实现

  1. def reduce(function, iterable, initializer=None): 


  2. it = iter(iterable) 


  3. if initializer is None: 


  4. value = next(it) 


  5. else: 


  6. value = initializer 


  7. for element in it: 


  8. value = function(value, element) 


  9. return value 



一个例子:

  1. from functools import reduce 



  2. def foo(x,y): 


  3. return x*10+y 


  4. result = reduce(foo,[1,3,5,7,9]) 



  5. print(type(result),result) 



filter()方法

filter(function, iterable)

Construct an iterator from those elements of iterable for which function returns true. iterable may be either a sequence, a container which supports iteration, or an iterator. If function is None, the identity function is assumed, that is, all elements of iterable that are false are removed.

Note that filter(function, iterable) is equivalent to the generator expression (item for item in iterable if function(item)) if function is not None and (item for item in iterable if item) if function is None.

先来个简单的例子,筛选奇数

  1. def is_odd(x): 


  2. return x%2 ==1 



  3. print(list(filter(is_odd,[1,2,3,4,5,6,7,8,9]))) 



举个例子,比如使用传说中的埃拉托色尼筛选法筛选出所有素数

  1. def odd_iter(): 


  2. n = 1 


  3. while True: 


  4. n = n + 2 


  5. yield n 



  6. def not_divisible(n): 


  7. return lambda x: x % n > 0 



  8. def primes(): 


  9. yield 2 


  10. it = odd_iter() 


  11. while True: 


  12. n = next(it) 


  13. yield n 


  14. it = filter(not_divisible(n), it) 



sorted()函数

自定义排序的一个函数. 举个简单的例子吧,感觉一是半会儿用不上.


  1. sorted([36, 5, -12, 9, -21], key=abs,reverse=True) 



python中的闭包

变量的作用域

不写了,回头发文章补齐

嵌套函数

函数里套函数,发文章的时候补齐

什么是闭包

看维基百科的学术定义

在计算机科学中,闭包(Closure)是词法闭包(Lexical Closure)的简称,是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。

说啥呢看不懂...

举个例子:

  1. def print_msg(): 


  2. msg = "hello world" 


  3. def printer(): 


  4. print(msg) 


  5. # 注意,这里没带括号,返回的是printer()这个函数的引用(指针) 


  6. return printer 



  7. # 这里等于通过print_msg()拿到了内部函数printer()的引用,所以printer这个变量指向了一个叫printer的函数 


  8. printer = print_msg() 


  9. print(printer) 


  10. printer() 




pic-1582723050329.png

不是所有嵌套函数都是闭包,就如同不是所有牛奶都是...跑题了

看箭头的位置,按照剧本,当函数执行完成后,其内部的局部变量应该已经销毁.

也就是说在print_msg()这函数执行完了之后,msg这个变量应该不存在了.

但是,BUT!!!

当我们通过print_msg()返回的引用去执行其内部的函数printer()的时候,msg这个变量又神奇的被打印出来了.

这里的printer变量就是一个闭包.

以下是我个人的理解,如果有错误,烦请指出. 因为python的GC使用的是引用计数机制.

所以当我们执行printer = print_msg()的时候,虽然print_msg()函数执行完了,但是在执行过程中,创建了一个字符串对象'hello world' (并将其引用赋值给了msg)和一个函数对象printer. 然后printer中又保留了到字符串对象msg的引用.所以在执行上述语句的时候发生了这么一个关系printer(外面的变量,这个名字起瞎了)-->printer--->msg

所以在函数print_msg执行完毕之后,变量msg的引用并没有变成0,这个变量依旧存在,没有被GC处理掉.

闭包有啥用

闭包避免了使用全局变量. 闭包允许函数将与其操作的某些数据(环境))关联起来.

在面向对象的编程中,对象允许我们将一些数据(属性)和一个或多个方法关联起来.

但是当对象中只有一个方法的时候,使用闭包或许是更好的选择.

  1. def foo(x): 


  2. def foo_inner(y): 


  3. return x+y 


  4. return foo_inner 



  5. foo1 = foo(5) 



  6. print(foo1(10)) 


  7. print(foo1(6)) 




pic-1582723050329.png

匿名函数

就是lambda表达式. lambda 入参 : 返回值

冒号前面是入参,冒号后面是返回值.用来简写函数的. 比如

  1. L = list(map(lambda x:x*x,[1,2,3,4,5])) 


  2. print(L) 



不好理解,新手别瞎JB用

装饰器

面向对象的语言中,万物都是对象,方法(函数)当然也是一个对象. 是对象就要有属性方法和引用. 函数对象有一个__name__的属性可以拿到函数的名称.

  1. def now():     


  2. print("2020-02-18") 


  3. foo = now 



  4. print(foo.__name__) 


  5. print(now.__name__) 



这俩输出肯定是一样的. 不懂的话C语言基础(非谭浩强版)从头学

那么如果现在我们想增强now()方法的功能,除了重写这个方法之外还有没有其他的办法?

想想嵌套函数貌似是可以的.

  1. def log(func): 


  2. def wrapper(*args, **kw): 


  3. #这里是我们想增强的代码 


  4. print('this is a log: function "%s" is called'%func.__name__) 


  5. return func(*args, **kw) 


  6. return wrapper 



  7. @log 


  8. def now(): 


  9. print("2020-02-18") 



这玩意儿就有点装饰器的样子了.

在now函数上面写个@log实际上就是在执行 log(now())

但是有个问题.

改造后的代码就是这个样子的.

  1. import functools 


  2. def log(func): 


  3. @functools.wraps(func) 


  4. def wrapper(*args, **kw): 


  5. #这里是我们想增强的代码 


  6. print('this is a log: function "%s" is called'%func.__name__) 


  7. return func(*args, **kw) 


  8. return wrapper 



  9. @log 


  10. def now(): 


  11. print("2020-02-18") 



  12. print(now.__name__) 



这里我们又发现一个神器的东西. 就是装饰器functools.wraps带参数...这玩意儿咋实现的呢?

看个例子:

  1. def log(text): 


  2. def decoraotor(func): 


  3. @functools.wraps(func) 


  4. def wrapper(*args, **kwargs): 


  5. print("%s %s" % (text, func.__name__)) 


  6. return func(*args, **kwargs) 


  7. return wrapper 


  8. return decoraotor 



  9. @log("Holy shit!") 


  10. def now(): 


  11. print("2020-02-18") 



真特么复杂...用到的时候翻笔记吧. 记不住记不住

偏函数

python中的偏函数不是数学上的偏函数(话说数学上的偏函数是啥,我也不知道...),看文档定义:

functools.partial(func, /, *args, **keywords)

Return a new partial object which when called will behave like func called with the positional arguments args and keyword arguments keywords. If more arguments are supplied to the call, they are appended to args. If additional keyword arguments are supplied, they extend and override keywords. Roughly equivalent to:

  1. def partial(func, /, *args, **keywords): 


  2. def newfunc(*fargs, **fkeywords): 


  3. newkeywords = {**keywords, **fkeywords} 


  4. return func(*args, *fargs, **newkeywords) 


  5. newfunc.func = func 


  6. newfunc.args = args 


  7. newfunc.keywords = keywords 


  8. return newfunc 



The partial() is used for partial function application which “freezes” some portion of a function’s arguments and/or keywords resulting in a new object with a simplified signature. For example, partial() can be used to create a callable that behaves like the int() function where the base argument defaults to two:

  1. from functools import partial 


  2. basetwo = partial(int, base=2) 


  3. basetwo.__doc__ = 'Convert base 2 string to an int.' 


  4. basetwo('10010') 



partial Objects

partial objects are callable objects created by partial(). They have three read-only attributes:

partial.func

A callable object or function. Calls to the partial object will be forwarded to func with new arguments and keywords.

partial.args

The leftmost positional arguments that will be prepended to the positional arguments provided to a partial object call.

partial.keywords

The keyword arguments that will be supplied when the partial object is called.

partial objects are like function objects in that they are callable, weak referencable, and can have attributes. There are some important differences. For instance, the__name__ and __doc__attributes are not created automatically. Also, partial objects defined in classes behave like static methods and do not transform into bound methods during instance attribute look-up.

看一个例子就得了.高级玩法,新手别瞎JB玩.

  1. def int2(x,base=2): 


  2. return int(x,base) 


  3. print(int2('10000000')) 



  4. int22 = functools.partial(int,base=2) 


  5. print(int22('10000000')) 



python随用随学20200118-函数的高级特性的更多相关文章

  1. C++复习11.函数的高级特性

    C++ 函数的高级特性 20131002 C++函数增加了重载(override), inline, const, virtual四种机制,重载和内联机制既可以用于全局函数,也可以用于类的成员函数.c ...

  2. python:函数的高级特性

    很多语言中,都允许把函数本身做为参数,传递给其它参数:即所谓的高阶函数.python中也有类似特性: 一.map/reduce.filter.sorted hadoop里的map-reduce思想在p ...

  3. Python序列函数、高级特性及高阶函数

    序列函数: enumerate: for循环时记录索引,逐个返回元组(i, item) sorted:返回新的有序列表 zip:压缩将多个序列的对应位置的元素组成元组 zip(*元组列表): 解压缩 ...

  4. 002-python函数、高级特性

    1.函数 1.1 定义函数 在Python中,定义一个函数要使用def语句,依次写出函数名.括号.括号中的参数和冒号:,然后,在缩进块中编写函数体,函数的返回值用return语句返回 自定义一个求绝对 ...

  5. python学习-33 max和min函数的高级使用

    1.简单比较 age_dic={'age1456':15,'age2':16,'xiaohong_age':12,'xiaoming_age4':18,'age5':10} print(max(age ...

  6. C++函数的高级特性

    对比于 C 语言的函数,C++增加了重载(overloaded).内联(inline).const 和 virtual 四种新机制.其中重载和内联机制既可用于全局函数也可用于类的成员函数,const ...

  7. C++函数的高级特性——小结

    相对于C语言,C++增加了重载(overload).内联(inline).const和virtual四种新机制. 1 重载 只能靠参数列表而不能紧靠返回值类型的不同来区分重载函数.编译器根据参数列表为 ...

  8. Python学习教程(Python学习视频_Python学些路线):Day06 函数和模块的使用

    Python学习教程(Python学习视频_Python学些路线):函数和模块的使用 在讲解本章节的内容之前,我们先来研究一道数学题,请说出下面的方程有多少组正整数解. $$x_1 + x_2 + x ...

  9. Python之旅Day3 文件操作 函数(递归|匿名|嵌套|高阶)函数式编程 内置方法

    知识回顾 常见五大数据类型分类小结:数字.字符串.列表.元组.字典 按存值个数区分:容器类型(列表.字典.元组) 标量原子(数字.字符串) 按是否可变区分:可变(列表.字典) 不可变(数字.字符串.元 ...

随机推荐

  1. Webpack实战(六):如何优雅地运用样式CSS预处理

    上一篇文章中,我主要分享了<Webpack如何分离样式文件>CSS 预处理器是一个能让你通过预处理器自己独有的语法来生成CSS的程序,css预处理指的是在开发中我们经常会使用一些样式预编译 ...

  2. Postman post csrf_token

    1.填入代码 var csrf_token = postman.getResponseCookie("csrftoken").value postman.clearGlobalVa ...

  3. Java入门 - 导读

    原文地址:http://www.work100.net/training/java 更多教程:光束云 - 免费课程 Java入门 Java 是由 Sun Microsystems 公司于1995年5月 ...

  4. Python的Excel操作及数据可视化

    Excel表操作 python操作excel主要用到xlrd和xlwt这两个库,即xlrd是读excel,xlwt是写excel的库. 安装xlrd pip install xlrd 简单的表格读取 ...

  5. IntelliJ IDEA编辑文件的时候CPU飙高问题的解决

    原文地址:https://www.javatang.com/archives/2018/04/26/25582403.html 上篇文章中说明了解决IntelliJ IDEA中文输入法无提示的问题,最 ...

  6. 夜晚 暴力 十点钟 jQuery 的 extend 实现 原理

    jQuery 的 extend 是怎么实现的 一看代码 喉咙 就不爽 这是 jQuery JavaScript Library v1.6 一看代码 多的 屁股疼 , 排名 前三 的 文章 可以去参考下 ...

  7. 2019杭电多校赛第九场 Rikka with Mista

    Problem Description Rikka is a fervent fan of JoJo's Bizarre Adventure. As the last episode of Golde ...

  8. 关于Xen

    尝试了各种方法搭建xen,尝试过从xenserver入手,但似乎最近时间端不允许访问,感谢我的老师,叫我从kvm入手,暂时记下xen中种种的坑,以后有缘再战.欢迎交流

  9. ASP.Net Core 发布到IIS Http Error 502.5 官方解决办法

    Http Error 502.5 - Process Failure 在IIS上发布.NET Core程序出现这个错误.网上搜索到的办法为什么总行不通呢? 有可能年代久远,现在的环境与当年不同,所以解 ...

  10. ios---cocoapods 安装与使用 (AFNetworking为例)

    cocoapods 安装与使用 一.CocoaPods是什么? CocoaPods是一个用Ruby写的.负责管理iOS项目中第三方开源库的工具,CocoaPods能让我们集中的.统一管理第三方开源库, ...