函数式编程就是封装成一个个函数,一次调用来完成复杂任务。

  函数式编程的一个特点是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数!

  • 高阶函数

  高阶函数就是将函数的变量名作为参数传入,内部再对该函数进行调用的函数。

  一个简单的高阶函数如下:

def add(x, y, f):
return f(x) + f(y)
x ==> -5
y ==> 6
f ==> abs
f(x) + f(y) ==> abs(-5) + abs(6) ==> 11
>>> add(-5, 6, abs)
11

  Python内建了map()、reduce()、filter()和sorted()等高阶函数。

  map()函数接收两个参数,一个是函数,一个是序列,map将传入的函数依次作用到序列的每个元素,并把结果作为新的list返回。

>>> def f(x):
... return x * x
...
>>> map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
[1, 4, 9, 16, 25, 36, 49, 64, 81]

  map()作为高阶函数,事实上它把运算规则抽象了,因此,我们不但可以计算简单的f(x)=x2,还可以计算任意复杂的函数,比如,把这个list所有数字转为字符串:

>>> map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9])
['', '', '', '', '', '', '', '', '']

  reduce把一个函数作用在一个序列[x1, x2, x3...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,其效果就是:

>>> def fn(x, y):
... return x * 10 + y
...
>>> reduce(fn, [1, 3, 5, 7, 9])
13579

  filter()函数是用于过滤序列的,传入一个函数和一个序列。filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素,如:

def not_empty(s):
return s and s.strip() filter(not_empty, ['A', '', 'B', None, 'C', ' '])
# 结果: ['A', 'B', 'C']

  sorted()函数是用于对序列进行排序,传入一个序列和一个默认函数为cmp的函数。只传入序列时,进行默认排序,如下:

>>> sorted([36, 5, 12, 9, 21])
[5, 9, 12, 21, 36]

  传入序列和函数时,依据传入的函数进行排序,如下:

def reversed_cmp(x, y):
if x > y:
return -1
if x < y:
return 1
return 0
>>> sorted([36, 5, 12, 9, 21], reversed_cmp)
[36, 21, 12, 9, 5]
  • 返回函数

  一个函数的返回值不是变量,而是函数。这种方式可以构成“闭包”,对程序有极大的应用,如装饰器。

  但是需要注意的是:返回函数不要引用任何循环变量,或者后续会发生变化的变量。

def count():
fs = []
for i in range(1, 4):
def f():
return i*i
fs.append(f)
return fs f1, f2, f3 = count()
>>> f1()
9
>>> f2()
9
>>> f3()
9

  如果一定要引用循环变量的话,方法是再创建一个函数,用该函数的参数绑定循环变量当前的值,无论该循环变量后续如何改变,已绑定到函数参数的值不变。

>>> def count():
... fs = []
... for i in range(1, 4):
... def f(j):
... def g():
... return j*j
... return g
... fs.append(f(i))
... return fs
...
>>> f1, f2, f3 = count()
>>> f1()
1
>>> f2()
4
>>> f3()
9
  • 匿名函数

  当Python中,传入函数不需要显式地定义时,就可以利用匿名函数直接带入;同时,由于匿名函数没有名字,不会出现函数名字冲突的情况。

  匿名函数的格式是:lambda x: x * x

  • 装饰器

  当希望在已有的函数基础上增加一部分功能,但是又不想重新改函数时,就可以使用装饰器,进行动态的修改,例如:对一个函数增加日志打印的功能。

def log(func):
def wrapper(*args, **kw):
print 'call %s():' % func.__name__
return func(*args, **kw)
return wrapper
@log
def now():
print '2013-12-25'
>>> now()
call now():
2013-12-25

另外,要改变打印内容时,用到3层套用,就是下面的情况:

import functools

def log(text):
def decorator(func):
@functools.wraps(func) # 装饰后不改变原函数的内置属性
def wrapper(*args, **kw):
print '%s %s():' % (text, func.__name__)
return func(*args, **kw)
return wrapper
return decorator
@log('execute')
def now():
print '2013-12-25'
>>> now()
execute now():
2013-12-25
  • 偏函数

  对于已有的函数,如果有默认的参数值,但是我们最近常调用的是另一个参数值时,可以使用偏函数,生成默认值为另一个参数的新函数。

>>> import functools
>>> int2 = functools.partial(int, base=2)
>>> int2('')
64
>>> int2('')
85

  相当于:

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

注:本文为学习廖雪峰Python入门整理后的笔记

Day-6: 函数式编程的更多相关文章

  1. angular2系列教程(六)两种pipe:函数式编程与面向对象编程

    今天,我们要讲的是angualr2的pipe这个知识点. 例子

  2. [学习笔记]JavaScript之函数式编程

    欢迎指导与讨论:) 前言 函数式编程能使我们的代码结构变得简洁,让代码更接近于自然语言,易于理解. 一.减少不必要的函数嵌套代码 (1)当存在函数嵌套时,若内层函数的参数与外层函数的参数一致时,可以这 ...

  3. 函数式编程之柯里化(curry)

    函数式编程curry的概念: 只传递给函数一部分参数来调用函数,然后返回一个函数去处理剩下的参数. var add = function(x) { return function(y) { retur ...

  4. 关于Java8函数式编程你需要了解的几点

    函数式编程与面向对象的设计方法在思路和手段上都各有千秋,在这里,我将简要介绍一下函数式编程与面向对象相比的一些特点和差异. 函数作为一等公民 在理解函数作为一等公民这句话时,让我们先来看一下一种非常常 ...

  5. Haskell 函数式编程快速入门【草】

    什么是函数式编程 用常规编程语言中的函数指针.委托和Lambda表达式等概念来帮助理解(其实函数式编程就是Lambda演算延伸而来的编程范式). 函数式编程中函数可以被非常容易的定义和传递. Hask ...

  6. java1.8函数式编程概念

    有关函数式编程 ·1 函数作为一等公民 特点:将函数作为参数传递给另外一个函数:函数可以作为另外一个函数的返回值 ·2 无副作用 函数的副作用指的是函数在调用过程中,除了给出了返回值外,还修改了函数外 ...

  7. 让JavaScript回归函数式编程的本质

    JavaScript是一门被误会最深的语言,这话一点不假,我们看下它的发展历史. 1995年,Netscape要推向市场,需要一门脚本语言来配套它.是使用一门已有的语言,还是发明一门新的语言,这也不是 ...

  8. python基础-函数式编程

    python基础-函数式编程  高阶函数:map , reduce ,filter,sorted 匿名函数:  lambda  1.1函数式编程 面向过程编程:我们通过把大段代码拆成函数,通过一层一层 ...

  9. python函数 与 函数式编程

    「函数」一词来源于数学,但编程中的「函数」概念,与数学中的函数是有很大不同的,具体区别,我们后面会讲,编程中的函数在英文中也有很多不同的叫法.在BASIC中叫做subroutine(子过程或子程序), ...

  10. Reactor事件驱动的两种设计实现:面向对象 VS 函数式编程

    Reactor事件驱动的两种设计实现:面向对象 VS 函数式编程 这里的函数式编程的设计以muduo为例进行对比说明: Reactor实现架构对比 面向对象的设计类图如下: 函数式编程以muduo为例 ...

随机推荐

  1. ORACLE 11g 静默安装

    整理下以前的文档,放到博客上面来以后能直接找到. 环境:oracle linux release 6.3 x86_84.oracle 11gR2 一.主机环境配置 1.1 gcc安装 在ISO文件的P ...

  2. 转载:vs2010 问题 >LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏

    原文链接:http://www.cnblogs.com/newpanderking/articles/3372969.html >LINK : fatal error LNK1123: 转换到 ...

  3. 斗地主[NOIP2015]

    题目描述 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54张牌来进行的扑克牌游戏.在斗地主中,牌的大小关系根据牌的数码表示如下:3<4< ...

  4. nopCommerce 3.9 大波浪系列 之 微信公众平台登录插件

    一.简介 插件源码下载:点击下载 微信公众平台网站授权帮助地址:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp142114084 ...

  5. 读书笔记(一)—— 浅析浏览器渲染过程和html中的文件加载

    在构建页面时,我们会在html中载入一个或多个css和js文件.或许大家都已经习惯了"最佳实践"中,css文件应该放在<head>标签中引入,而js文件则是放在< ...

  6. hdu--1104--Remainder(简单的bfs)

    Remainder Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total S ...

  7. Head First 设计模式目录

    这确实是本好书啊,看其他的书,都会有种看了就忘,看着看着就会有种昏昏欲睡的感脚,然而,这本书却能让我在看了之后记住自己看了些什么. 并且在本书的开头,作者也在一个劲的告诉你如何让自己来记住自己看了什么 ...

  8. SecureCRT 常用命令大全

    常用命令:一.ls 只列出文件名 (相当于dir,dir也可以使用) -A:列出所有文件,包含隐藏文件. -l:列表形式,包含文件的绝大部分属性. -R:递归显示. --help:此命令的帮助. 二. ...

  9. OpenOfice将offic转为pdf并且在web显示

    1.将office首先要安装OpenOfice,傻瓜式安装就好了,之后可以使用下列代码将word转为pdf.这个需要导入jodconverter-2.2.2里的 ja r包 import java.i ...

  10. Weex的原生开发

    weex概念与特性 最形象的理解就是类似react native. Weex几大特点: 1.帮助你构建原生应用 与 Web App.HTML5 App 或 hybrid App 不同,您可以使用 We ...