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和一个listlist里的元素依次通过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和一个listf必须接受两个参数,取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,函数flist中每个元素进行判断,返回TrueFalse,过滤掉不符合条件的元素,生成由符合条件的元素组成的序列。

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

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))

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

一个需要注意的点:返回函数不要引用任何循环变量,或者后续会发生变化的变量。这个可以看看廖雪峰老师慕课网上的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表示一个二进制的类型转换函数。

目录
相关文章
|
24天前
|
机器学习/深度学习 Python
堆叠集成策略的原理、实现方法及Python应用。堆叠通过多层模型组合,先用不同基础模型生成预测,再用元学习器整合这些预测,提升模型性能
本文深入探讨了堆叠集成策略的原理、实现方法及Python应用。堆叠通过多层模型组合,先用不同基础模型生成预测,再用元学习器整合这些预测,提升模型性能。文章详细介绍了堆叠的实现步骤,包括数据准备、基础模型训练、新训练集构建及元学习器训练,并讨论了其优缺点。
43 3
|
4天前
|
Python 容器
Python学习的自我理解和想法(9)
这是我在B站跟随千锋教育学习Python的第9天,主要学习了赋值、浅拷贝和深拷贝的概念及其底层逻辑。由于开学时间紧张,内容较为简略,但希望能帮助理解这些重要概念。赋值是创建引用,浅拷贝创建新容器但元素仍引用原对象,深拷贝则创建完全独立的新对象。希望对大家有所帮助,欢迎讨论。
|
6天前
|
存储 索引 Python
Python学习的自我理解和想法(6)
这是我在B站千锋教育学习Python的第6天笔记,主要学习了字典的使用方法,包括字典的基本概念、访问、修改、添加、删除元素,以及获取字典信息、遍历字典和合并字典等内容。开学后时间有限,内容较为简略,敬请谅解。
|
10天前
|
存储 程序员 Python
Python学习的自我理解和想法(2)
今日学习Python第二天,重点掌握字符串操作。内容涵盖字符串介绍、切片、长度统计、子串计数、大小写转换及查找位置等。通过B站黑马程序员课程跟随老师实践,非原创代码,旨在巩固基础知识与技能。
|
9天前
|
程序员 Python
Python学习的自我理解和想法(3)
这是学习Python第三天的内容总结,主要围绕字符串操作展开,包括字符串的提取、分割、合并、替换、判断、编码及格式化输出等,通过B站黑马程序员课程跟随老师实践,非原创代码。
|
6天前
|
Python
Python学习的自我理解和想法(7)
学的是b站的课程(千锋教育),跟老师写程序,不是自创的代码! 今天是学Python的第七天,学的内容是集合。开学了,时间不多,写得不多,见谅。
|
5天前
|
存储 安全 索引
Python学习的自我理解和想法(8)
这是我在B站千锋教育学习Python的第8天,主要内容是元组。元组是一种不可变的序列数据类型,用于存储一组有序的元素。本文介绍了元组的基本操作,包括创建、访问、合并、切片、遍历等,并总结了元组的主要特点,如不可变性、有序性和可作为字典的键。由于开学时间紧张,内容较为简略,望见谅。
|
6天前
|
存储 索引 Python
Python学习的自我理解和想法(4)
今天是学习Python的第四天,主要学习了列表。列表是一种可变序列类型,可以存储任意类型的元素,支持索引和切片操作,并且有丰富的内置方法。主要内容包括列表的入门、关键要点、遍历、合并、判断元素是否存在、切片、添加和删除元素等。通过这些知识点,可以更好地理解和应用列表这一强大的数据结构。
|
6天前
|
索引 Python
Python学习的自我理解和想法(5)
这是我在B站千锋教育学习Python的第五天笔记,主要内容包括列表的操作,如排序(`sort()`、``sorted()``)、翻转(`reverse()`)、获取长度(`len()`)、最大最小值(`max()`、``min()``)、索引(`index()`)、嵌套列表和列表生成(`range`、列表生成式)。通过这些操作,可以更高效地处理数据。希望对大家有所帮助!
|
12天前
|
安全 程序员 Python
Python学习的自我理解和想法(1)
本篇博客记录了作者跟随B站“黑马程序员”课程学习Python的第一天心得,涵盖了`print()`、`input()`、`if...else`语句、三目运算符以及`for`和`while`循环的基础知识。通过实际编写代码,作者逐步理解并掌握了这些基本概念,为后续深入学习打下了良好基础。文中还特别强调了循环语句的重要性及其应用技巧。
下一篇
DataWorks