python学习(3)函数式编程

1.函数式编程(functional programming)

是一种编程方法,或者说是编程模式,它将电脑运算视为函数的计算、不需要变量因而不会产生副作用、支持高阶函数(可以接受函数作为参数)。

Python并不是纯的函数式编程,它允许有变量,支持闭包,有限的支持匿名函数。

与以前的C++不同的是python的变量是可以指向函数的,而函数名其实也是一个指向函数的变量

可以看看下面的例子:

f = abs

f(-10)

当然我们可以想到指向函数的变量其实也可以作为函数参数,这就相当于函数作为参数,就是我们说的高阶函数

看下面的例子:

def add(x, y, f):

return f(x) + f(y)

 add(-5, 6, abs)

 

2.几个python内置的高阶函数

map():

接受一个函数f和一个list,list里的元素依次通过f的处理,然后生成一个新的list。

看这个例子:

def format_name(s):

    return s[0].upper()+s[1:].lower()

print map(format_name, ['sam', 'LIly', 'TOM'])

输出:['Sam', 'Lily', 'Tom']

reduce():

接受一个函数f和一个list,f必须接受两个参数,取list中前两个元素用f处理,结果再作为参数和后面的元素一起用f处理,依次类推。

看下面的例子:

from functools import reduce

def add(x, y):

     return x + y

reduce(add, [1, 3, 5, 7, 9])

输出:25

filter():

用于过滤序列,接受一个函数f和一个list,函数f对list中每个元素进行判断,返回True或False,过滤掉不符合条件的元素,生成由符合条件的元素组成的序列。

例如下面这个过滤偶数的例子:

def is_odd(x):

return x % 2 == 1

filter(is_odd, [1, 4, 6, 7, 9, 12, 17])

 

sorted():

用于对list进行排序,第二个参数可以省略也可以传入一个函数cmp,来定义排序的规则:顺序的返回-1,逆序返回1,相等返回0。第三个参数如果设为reverse=True可以在原来的基础上逆序排序。

看下面的例子:

def cmp_ignore_case(s1, s2):

    if s1.upper()<s2.upper():

        return -1

    else:

        return 1

print sorted(['bob', 'about', 'Zoo', 'Credit'], key=cmp_ignore_case, reverse=True)

结果:['Zoo', 'Credit', 'bob', 'about']

 

3.返回函数与闭包

返回函数:

Python可以返回函数,但有一点需要注意的:

看这个例子:

def calc_prod(lst):

    def prod(x1, x2):

        return x1 * x2

    def c_prod():

        return reduce(prod, lst)

    return c_prod

f = calc_prod([1, 2, 3, 4])

print f()

输出:24

这里返回函数的时候并不会执行,再调用f()的时候才会执行。

闭包:

先简单的下个定义:内层函数引用了外层函数的变量(参数也算变量),然后返回内层函数的情况,称为闭包(Closure

但是为什么要这样子做呢?我们结合下面这个例子来理解一下:

def line_conf(a, b):

    def line(x):

        return ax + b

    return line

line1 = line_conf(1, 1)

line2 = line_conf(4, 5)

print(line1(5), line2(5))

显然如果我们只是定义一个接受a、b、x三个参数的函数也是可以的,但这样我们每次就需要传入三个参数,显然麻烦很多,特别是当a、b两个参数较少改变的时候,上面代码使用闭包的简便性就体现出来了。这就是说闭包能提高程序的复用性。

一个需要注意的点:返回函数不要引用任何循环变量,或者后续会发生变化的变量。这个可以看看廖雪峰老师慕课网上的python进阶教程深入了解。

 

4.匿名函数

Python匿名函数的使用比Java的简单得多:用关键字lambda且只能有一个表达式。

看下面的例子:

print filter(lambda s:s and len(s.strip()) > 0, ['test', None, '', 'str', '  ', 'END'])

这个例子的功能是过滤空字符串,冒号前面的x是参数,后面是表达式。

 

5.装饰器

装饰器(Decorator用于增强函数的功能。本质上就是一个高阶函数,它接收一个函数作为参数,然后,返回一个新函数。

我们可以用@语句简化像f = decorate(f)这样的代码。

看下面的例子:

def log(f):

    def fn(x):

        print 'call ' + f.__name__ + '()...'

        return f(x)

return fn

@log

def factorial(n):

    return reduce(lambda x,y: x*y, range(1, n+1))

print factorial(10)

输出:

call factorial()...

3628800

但是,我们发现log()函数只适用于一个参数的函数。为了让它适用各种参数数量,我们需要做一些修改:

def log(f):

    def fn(*args, **kw):

        print 'call ' + f.__name__ + '()...'

        return f(*args, **kw)

return fn

然后有时,我们需要log()函数打印不同的语句,这就需要我们对装饰器传入参数。

思路是这个样子的:带参数的log函数首先返回一个decorator函数,再让这个decorator函数接收my_func并返回新函数。

看下面的例子:

def log(prefix):

    def log_decorator(f):

        def wrapper(*args, **kw):

            print '[%s] %s()...' % (prefix, f.__name__)

            return f(*args, **kw)

        return wrapper

    return log_decorator

 

@log('DEBUG')

def test():

    pass

print test()

输出:

[DEBUG] test()...

None

装饰器有时会改变函数的一些属性,比如函数名等,为了保存原有的函数信息,我们可以在参数为原函数的函数下加一句 @functools.wraps(f)

 

6.偏函数

我们可以用 functools.partial() 减少原函数参数的数量,创建一个新函数。

看下面的例子:

int2 = functools.partial(int, base=2)

Int函数默认第二个参数为10,表示进制,我们也可以改变第二个参数,例子的int2表示一个二进制的类型转换函数。

时间: 2024-12-02 06:23:52

python学习(3)函数式编程的相关文章

Python Decorator 和函数式编程

来源:https://www.oschina.net/translate/decorators-and-functional-python Python Decorator 和函数式编程 英文原文:Decorators and Functional Python Decorators 是Python中最重要的特性之一. 它除了使Python更好用外的, 它还能帮助我们以一种更有趣的方法考虑问题--函数式编程的方法 我会尝试着从零开始解释Decorator是怎么工作的. 首先, 我们会介绍一些帮助

Python中的函数式编程

虽然人们总把Python当作过程化的,面向对象的语言,但是他实际上包含了函数化编程中,你需要的任何东西.这篇文章主要讨论函数化编程的一般概念,并说明用Python来函数化编程的技术. 我们最好从艰难的问题开始出发:"到底什么是函数化编程呢?"其中一个答案可能是这样的,函数化编程就是你在使用Lisp这样的语言时所做的(还有Scheme,Haskell,ML,OCAML,Mercury,Erlang和其他一些语言).这是一个保险的回答,但是它解释得并不清晰.不幸的是对于什么是函数化编程,很

Fn.py:享受Python中的函数式编程

尽管Python事实上并不是一门纯函数式编程语言,但它本身是一门多范型语言,并给了你足够的自由利用函数式编程的 便利.函数式风格有着各种理论与实际上的好处(你可以在Python的文档中找到这个列表): 形式上可证 模块性 组合性 易于调试及测试 虽然这份列表已经描述得够清楚了,但我还是很喜欢Michael O.Church在他的文章"函数式程序极少腐坏(Functional programs rarely rot)"中对函数式编程的优点所作的描述.我在PyCon UA 2012期间的讲

Python 进阶_函数式编程

目录 目录 函数式编程 Python 函数式编程的特点 高阶函数 匿名函数 lambda 函数式编程相关的内置函数 filter 序列对象过滤器 map reduce 折叠 自定义的排序函数 最后 函数式编程 首先要确定一点就是:函数 != 函数式,函数式编程是一种编程的范式. 特点: 把计算视为函数而非指令 纯函数式编程,不需要变量,没有副作用,测试简单 支持高阶函数,代码简洁 Python 函数式编程的特点 需要注意的是,Python 不是也不可能会成为一种纯函数是编程语言,但 Python

准备充分了嘛就想学函数式编程?(Part 6)

本文讲的是准备充分了嘛就想学函数式编程?(Part 6), 第一步,理解函数式编程概念是最重要的一步,同时也是最难的一步.如果你从正确的角度或方法来理解的话,它也未必会有那么难. 回顾之前的部分: Part 1, Part 2, Part 3, Part 4, Part 5 现在该做什么? 现在你已经学会了所有这些新东西了,你可能在想,"现在该干什么?我如何在日常编程中使用它?" 这得看情况.如果你会使用纯函数式语言(如 Elm 或 Haskell)编程,那么你可以尝试所有这些想法.这

王亟亟的Python学习之路(八)-函数式编程,map(),reduce(),filter()

转载请注明出处:王亟亟的大牛之路 首先在这里祝愿大家,新年快乐,工作顺利,BUG少少!!! 本来说是在春节假期内继续维持着写文章的进度,但是还是偷懒了几天(打了4天SC2哈哈哈) 今天上的是关于Python的文章,毕竟在亲戚家拜年,懒得插各类手机调试什么的,况且确实好久没有弄Python了,就写了,废话不多,开始正题!! 函数式编程 函数是什么? 把复杂的操作化为简单的函数分解成简单的操作,这种操作就是面向过程,也就是C这类的实现的大体概念. 函数式是什么? 函数没有变量,任意一个函数,只要输入

Python函数式编程指南(一):函数式编程概述

  这篇文章主要介绍了Python函数式编程指南(一):函数式编程概述,本文讲解了什么是函数式编程概述.什么是函数式编程.为什么使用函数式编程.如何辨认函数式风格等核心知识,需要的朋友可以参考下 1. 函数式编程概述 1.1. 什么是函数式编程? 函数式编程使用一系列的函数解决问题.函数仅接受输入并产生输出,不包含任何能影响产生输出的内部状态.任何情况下,使用相同的参数调用函数始终能产生同样的结果. 在一个函数式的程序中,输入的数据"流过"一系列的函数,每一个函数根据它的输入产生输出.

为什么用 JavaScript 学习函数式编程?(软件编写)(第二部分)

本文讲的是为什么用 JavaScript 学习函数式编程?(软件编写)(第二部分), 烟雾的方块艺术 -MattysFlicks -(CC BY 2.0) 注意:这是从基础学习函数式编程和使用 JavaScript ES6+ 撰写软件的第二部分.保持关注,接下来还有很多!第一篇 | 第三篇 > 忘掉你认为知道的关于 JavaScript 的一切,用初学者的眼光去看待它.为了帮助你做到这一点,我们将会从头复习一下 JavaScript 的基础,就像你与其尚未谋面一样.如果你是初学者,那你就很幸运了

Python函数式编程指南(二):从函数开始

  这篇文章主要介绍了Python函数式编程指南(二):从函数开始,本文讲解了定义一个函数.使用函数赋值.闭包.作为参数等内容,需要的朋友可以参考下 2. 从函数开始 2.1. 定义一个函数 如下定义了一个求和函数: 代码如下: def add(x, y): return x + y 关于参数和返回值的语法细节可以参考其他文档,这里就略过了. 使用lambda可以定义简单的单行匿名函数.lambda的语法是: 代码如下: lambda args: expression 参数(args)的语法与普