函数式编程

原创 2016年08月30日 11:02:17
Edit

函数式编程

特点:允许把函数本身作为参数传入另一个函数,还允许返回一个函数。 
python对函数式编程提供部分支持,由于python允许使用变量,因此,python不是纯函数式编程语言。

高阶函数

定义:一个函数可以接受另外一个函数作为参数,就是高阶函数。 
python可以写高阶函数:

  1. 变量可以指向函数
  2. 函数名也是变量 
    例如:
1.def add(x,y,f):
2.    return f(x)+f(y)
1.>>>add(-5,6,abs)
2.11

map()

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

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

reduce()

定义:该函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算。 
例如:

1.>>> from functools import reduce
2.>>> def fn(x, y):
3....     return x * 10 + y
4....
5.>>> reduce(fn, [1, 3, 5, 7, 9])
6.13579

举一个同时用mapreduce的例子:

1.>>> from functools import reduce
2.>>> def fn(x, y):
3....     return x * 10 + y
4....
5.>>> def char2num(s):
6....     return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]
7....
8.>>> reduce(fn, map(char2num, '13579'))
9.13579

filter()

定义:fliter()接收一个函数和一个序列,根据传入函数的返回值是Ture还是False决定保留还是丢弃该元素。 
例如:

1.def is_odd(n):
2.    return n % 2 == 1
3.
4.list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15]))
5.# 结果: [1, 5, 9, 15]

sorted()

定义:key函数用来实现自定义排序,reverse=True实现反向排序。 
例如:

  1. 直接进行排序
1.>>> sorted([36, 5, -12, 9, -21])
2.[-21, -12, 5, 9, 36]
  1. 自定义进行排序
1.>>> sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower)
2.['about', 'bob', 'Credit', 'Zoo']
  1. 反向排序
1.>>> sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower, reverse=True)
2.['Zoo', 'Credit', 'bob', 'about']

返回函数

函数可以作为返回值

  • 定例子如下:
1.def lazy_sum(*args):
2.    def sum():
3.        ax = 0
4.        for n in args:
5.            ax = ax + n
6.        return ax
7.    return sum
  • 调用时:
1.>>> f = lazy_sum(1, 3, 5, 7, 9)
2.>>> f
3.<function lazy_sum.<locals>.sum at 0x101c6ed90>
4.>>> f()
5.25
  • 注意: 
    当我们调用lazy_sum()时,每次调用都会返回一个新的函数,即使传入相同的参数
1.>>> f1 = lazy_sum(1, 3, 5, 7, 9)
2.>>> f2 = lazy_sum(1, 3, 5, 7, 9)
3.>>> f1==f2
4.False

闭包

  • 定义:当一个函数返回一个函数时,相关的参数和变量都保存在返回的函数中,这种称为“闭包”。
  • 注意:返回闭包时,返回函数不要引用任何循环变量,或者后续会发生变化的变量,也就是说,返回函数里面的变量必须在这个函数的任何地方都跟外界的函数没有关系的。
  • 错误例子
1.def count():
2.    fs = []
3.    for i in range(1, 4):
4.        def f():
5.             return i*i
6.        fs.append(f)
7.    return fs
8.
9.f1, f2, f3 = count()

·结果

1.>>> f1()
2.9
3.>>> f2()
4.9
5.>>> f3()
6.9
  • 改正后:
1.def count():
2.    def f(j):
3.        def g():
4.            return j*j
5.        return g
6.    fs = []
7.    for i in range(1, 4):
8.        fs.append(f(i)) # f(i)立刻被执行,因此i的当前值被传入f()
9.    return fs

结果:

1.>>> f1, f2, f3 = count()
2.>>> f1()
3.1
4.>>> f2()
5.4
6.>>> f3()
7.9

匿名函数

  • 定义:关键字lambda表示匿名函数,冒号前面的x表示函数的参数

例子:

1.>>>list(map(lambda x:x*x,[1,2,3,4,5,6,7]))
2.[1,4,9,16,25,36,49]

相当于:

1.def f(x):
2.    return x*x
  • 注意:只能有一个表达式,不用写return,返回值就是该式的表达结果。
  • 好处: 
    1. 不必担心函数名冲突。
    2. 匿名函数是一个函数对象,可以把匿名函数赋值给一个变量。
    3. 匿名函数可以作为返回值返回。

装饰器

函数也是一个对象,函数对象有一个_name_属性,可以拿到函数名字

  • 定义:在代码运行期间动态增加功能的函数,称为“装饰器”。比如,在函数调用前后自动打印日志,同时又不修改now()函数的定义。
  • 本质是一个返回函数的高阶函数。所以接受一个函数作为参数,并返回一个函数。
  • 使用

例如一个打印日志的decorator

1.def log(func):
2.    def wrapper(*args,**kw):
3.        print('call  %s():' % func._name_)
4.        return func(*args,**kw)
5.    return wrapper

在使用时,我们要借助Python的@语法,把decorator置于函数的定义处:

1.@log
2.def now():
3.    print('2016-8-30')

调用now()函数,不仅会运行now()函数本身,还会运行now()函数前的打印日志函数:

1.>>>now()
2.call now():
3.2016-8-30

这相当于:

1.>>>now=log(now)
  • 高级使用

如果decorator本身需要传入参数,比如要自定义log文本:

1.def log(text):
2.    def decorator(func):
3.        def wrapper(*args, **kw):
4.            print('%s %s():' % (text, func.__name__))
5.            return func(*args, **kw)
6.        return wrapper
7.    return decorator

用法:

1.@log('execute')
2.def now():
3.    print('2016-8-30')

结果:

1.>>>now()
2.execute now():
3.2016-8-30

相当于:

1.>>>now=log('execute')(now)

首先执行log('execute'),返回值是decorator函数,再调用 
返回的函数,参数是now函数,返回值最终是wrapper函数。

  • 注意:

经decorator修饰过的函数,它们的_name_已经从原来的now变成了wrapper了,需要用functools.wraps把函数名字复制下来。 
代码如下:

1.#!/usr/bin/env python3 
2. # -*- coding: utf-8 -*- 
3.
4.
5.import functools 
6.
7.def log(func): 
8.    #@functools.wraps(func) 
9.    def wrapper(*args, **kw): 
10.        print('call %s():' % func.__name__) 
11.        return func(*args, **kw) 
12.    return wrapper 
13.
14.
15.@log 
16.def now(): 
17.    print('2015-3-25') 
18.
19.now() 
20.print(now.__name__)
21.
22.def logger(text): 
23.    def decorator(func): 
24.        @functools.wraps(func) 
25.        def wrapper(*args, **kw): 
26.            print('%s %s():' % (text, func.__name__)) 
27.            return func(*args, **kw) 
28.        return wrapper 
29.    return decorator 
30.
31.@logger('DEBUG') 
32.def today(): 
33.    print('2015-3-25') 
34.
35.today() 
36.print(today.__name__) 

运行结果:

1.call now():
2.2015-3-25
3.wrapper
4.DEBUG today():
5.2015-3-25
6.today

偏函数

  • 定义:functools.partial的作用就是把一个函数的某些参数给固定住(也就是设定默认值),返回一个新的函数,是调用函数变得简单。

例如:

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

调用时:

1.>>>int2('100000')
2.32

用偏函数实现同样的功能:

1.>>> import functools
2.>>> int2 = functools.partial(int, base=2)
3.>>> int2('1000000')
4.64
5.>>> int2('1010101')
6.85
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

Java 8函数式编程 范例

  • 2017-10-12 17:56
  • 383KB
  • 下载

《java 8函数式编程》

  • 2017-08-20 20:50
  • 11.73MB
  • 下载

函数式编程!

简介:函数式编程语言在学术领域已经存在相当长一段时间了,但是从历史上看,它们没有丰富的工具和库可供使用。随着 .NET 平台上的 Haskell 的出现,函数式编程变得更加流行。一些传统的编程语言...

Java 8函数式编程

  • 2017-08-17 23:03
  • 11.73MB
  • 下载

JavaScript函数式编程.pdf

  • 2017-04-09 08:22
  • 37.55MB
  • 下载

python 函数式编程

函数式编程 首先要确定一点就是:函数 != 函数式,函数式编程是一种编程的范式。  特点: 把计算视为函数而非指令纯函数式编程,不需要变量,没有副作用,测试简单支持高阶函数,代码简洁 ...

Scala函数式编程.pdf

  • 2017-05-30 21:30
  • 73.71MB
  • 下载

Java8函数式编程PDF

  • 2017-08-27 13:54
  • 11.66MB
  • 下载

JavaScript小特性(6)——函数式编程

http://rolfzhang.com/articles/793.html
  • Baple
  • Baple
  • 2014-09-24 15:57
  • 444

JS函数式编程指南

  • 2017-05-01 17:49
  • 3.11MB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)