map, filter, and reduce

Python提供了几个函数,使得能够进行函数式编程。这些函数都拥有方便的特性,他们可以能够很方便的用python编写。

函数式编程都是关于表达式的。我们可以说,函数式编程是一种面向表达式的编程。

Python提供的面向表达式的函数有:

map(aFunction, aSequence)

filter(aFunction, aSequence)

reduce(aFunction, aSequence)

lambda

list comprehension

map

我们对list和其他sequence所做的常见事情之一是对每个item应用操作并收集结果。

例如,可以使用for循环轻松完成更新list中的所有items的更新操作:

>>> items = [1, 2, 3, 4, 5]
>>> squared = []
>>> for x in items:
squared.append(x ** 2)
>>> squared
[1, 4, 9, 16, 25]

由于这是一个常见的操作,实际上我们有一个内置的功能,可以替我们完成大部分的工作。

map(aFunction,aSequence)函数将传入的函数应用于可迭代对象中的每个item,并返回一个包含所有函数调用结果的list。

>>> items = [1,2,3,4,5]
>>> def sqr(x):return x ** 2
>>> list(map(sqr,items))
[1,4,9,16,25]

我们通过一个用户定义的函数应用于list的每个item。 map调用每个list中item上的sqr,并将所有返回值收集到一个新list中。因为map需要传入一个函数,所以它也恰好是lambda常规用的地方之一:

>>> list(map((lambda x: x **2), items))
[1, 4, 9, 16, 25]

在上面的简短示例中,lambda函数给列表中的每个item都做了平方运算。如前所述,map是这样定义的:

map(aFunction, aSequence)

尽管我们仍然使用lamda作为函数,但我们可以将函数列表作为序列:

def square(x):
return (x**2)
def cube(x):
return (x**3) funcs = [square, cube]
for r in range(5):
value = map(lambda x: x(r), funcs)
print value

输出结果:

[0,0]
[1,1]
[4,8]
[9,27]
[16,64]

因为使用map等价于循环,所以我们总是可以编写一个通用的映射工具:

>>> def mymap(aFunc, aSeq):
result = []
for x in aSeq: result.append(aFunc(x))
return result >>> list(map(sqr, [1, 2, 3]))
[1, 4, 9]
>>> mymap(sqr, [1, 2, 3])
[1, 4, 9]
>>>

由于map是内置的,所以它始终可用,并始终以相同的方式工作。它也有一些性能上的好处,因为它通常比手动编码的循环更快。除此之外,map可以以更高级的方式使用。例如,在给定多个序列参数的情况下,它将并行采取的项目作为不同的参数发送给函数:

>>> pow(3,5)
243
>>> pow(2,10)
1024
>>> pow(3,11)
177147
>>> pow(4,12)
16777216
>>>
>>> list(map(pow, [2, 3, 4], [10, 11, 12]))
[1024, 177147, 16777216]
>>>

如上例所示,对于多个序列,map()需要N个序列的N参数函数。在这个例子中,pow函数在每个调用中都有两个参数。

下面是另一个map()做两个列表元素添加的例子:

x = [1,2,3]
y = [4,5,6] from operator import add
print map(add, x, y) # output [5, 7, 9]

地图调用类似于列表理解表达式。但是map对每个项目应用了一个函数调用,而不是一个任意的表达式。由于这个限制,它是不太一般的工具。然而,在某些情况下,映射可能比列表解析式更快,比如映射内置函数。而且map需要更少的编码。

如果函数是None,则假定身份函数;如果有多个参数,则map()返回一个包含所有迭代(一种转置操作)中相应项目的元组的列表。可迭代的参数可能是一个序列或任何可迭代的对象;结果总是一个列表。

>>> m = [1,2,3]
>>> n = [1,4,9]
>>> new_tuple = map(None, m, n)
>>> new_tuple
[(1, 1), (2, 4), (3, 9)]

对于Python3,我们可能想使用itertools.zip_longest来代替:

>>> m = [1,2,3]
>>> n = [1,4,9]
>>> from itertools import zip_longest
>>> for i,j in zip_longest(m,n):
... print(i,j)
...
1 1
2 4
3 9

zip_longest()使得迭代器聚合来自两个迭代器(m&n)的元素。

filter、reduce

顾名思义,filter提取函数返回True的序列中的每个元素。减少函数的意图稍微不明显。该功能通过提供的功能组合元素将列表缩小为单个值。 map函数是用于函数式编程的Python内建函数中最简单的函数。

这些工具将函数应用于序列和其他迭代。filter根据作为过滤器的测试功能过滤出iterm,并将功能应用到item对和减少的运行结果。因为他们返回迭代器,范围和过滤器都需要列表调用,以在Python 3.0中显示所有的结果。

例如,下面的filter调用会挑选出序列中小于零的项目:

>>> list(range(-5,5))
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4]
>>>
>>> list( filter((lambda x: x < 0), range(-5,5)))
[-5, -4, -3, -2, -1]
>>>

在该函数返回true的序列或迭代中的项目,结果被添加到结果列表。像map一样,这个函数大致相当于一个for循环,但它是内置的和快速的:

>>> result = []
>>> for x in range(-5, 5):
if x < 0:
result.append(x) >>> result
[-5, -4, -3, -2, -1]

这里是filter()的另一个用例:找到两个列表的交集:

a = [1,2,3,5,7,9]
b = [2,3,5,6,7,8]
print filter(lambda x: x in a, b) # prints out [2, 3, 5, 7]

请注意,我们可以在列表理解上做同样的事情:

a = [1,2,3,5,7,9]
b = [2,3,5,6,7,8]
print [x for x in a if x in b] # prints out [2, 3, 5, 7]

reduce是Python 3.0中的functools。这是更复杂的。它接受一个迭代器来处理,但它本身不是一个迭代器。它返回一个单一的结果:

>>> from functools import reduce
>>> reduce( (lambda x, y: x * y), [1, 2, 3, 4] )
24
>>> reduce( (lambda x, y: x / y), [1, 2, 3, 4] )
0.041666666666666664

在每个步骤中,减少将当前产品或部门以及列表中的下一个项目传递给传入的lambda函数。默认情况下,序列中的第一个项目初始化起始值。

这里是第一个调用的for循环版本,在循环内部进行了硬编码:

>>> L = [1, 2, 3, 4]
>>> result = L[0]
>>> for x in L[1:]:
result = result * x
>>> result
24

让我们来制作我们自己的reduce版本。

>>> def myreduce(fnc, seq):
tally = seq[0]
for next in seq[1:]:
tally = fnc(tally, next)
return tally >>> myreduce( (lambda x, y: x * y), [1, 2, 3, 4])
24
>>> myreduce( (lambda x, y: x / y), [1, 2, 3, 4])
0.041666666666666664
>>>

我们可以连接一串字符串来做一个句子。使用迪杰斯特拉关于错误的着名报价:

import functools
>>> L = ['Testing ', 'shows ', 'the ', 'presence', ', ','not ', 'the ', 'absence ', 'of ', 'bugs']
>>> functools.reduce( (lambda x,y:x+y), L)
'Testing shows the presence, not the absence of bugs'
>>> We can get the same result by using join :
>>> ''.join(L)
'Testing shows the presence, not the absence of bugs'

我们也可以使用运算符来产生相同的结果:

>>> import functools, operator
>>> functools.reduce(operator.add, L)
'Testing shows the presence, not the absence of bugs'

内置的reduce还允许在序列中的项目之前放置一个可选的第三个参数,以作为序列为空时的默认结果。

[译]PYTHON FUNCTIONS - MAP, FILTER, AND REDUCE的更多相关文章

  1. python库函数Map, Filter and Reduce的用法

    python中有三个函数式编程极大的简化了程序的复杂性,这里就做一下讨论和记录. 一 Map:应用在链表输入所有元素的函数,它的格式如下所示: map(function_to_apply, list_ ...

  2. Python之内建函数Map,Filter和Reduce

    Python进阶 map,filter, reduce是python常用的built-in function. 且常与lambda表达式一起用. 其中: map 形式:map(function_to_ ...

  3. Python Map, Filter and Reduce

    所属网站分类: python基础 > 函数 作者:慧雅 原文链接: http://www.pythonheidong.com/blog/article/21/ 来源:python黑洞网 www. ...

  4. Map,Filter和Reduce

    转自:https://www.aliyun.com/jiaocheng/444967.html?spm=5176.100033.1.13.xms8KG 摘要:Map,Filter和Reduce三个函数 ...

  5. Map, filter and reduce

    To add up all the numbers in a list, you can use a loop like this: Total is initialized to 0. Each t ...

  6. python的map函数和reduce函数(转)

    map函数 map()函数 map()是 Python 内置的高阶函数,它接收一个函数 f 和一个 list,并通过把函数 f 依次作用在 list 的每个元素上,得到一个新的 list 并返回. 例 ...

  7. js Array 中的 map, filter 和 reduce

    原文中部分源码来源于:JS Array.reduce 实现 Array.map 和 Array.filter Array 中的高阶函数 ---- map, filter, reduce map() - ...

  8. [Python学习笔记-002] lambda, map, filter and reduce

    1. lambda lambda, 即匿名函数,可以理解为跟C语言的宏类似.例如: >>> max = lambda x, y: x if x > y else y >& ...

  9. python的高阶函数(map,filter,sorted,reduce)

    高阶函数 关注公众号"轻松学编程"了解更多. 1.MapReduce MapReduce主要应用于分布式中. 大数据实际上是在15年下半年开始火起来的. 分布式思想:将一个连续的字 ...

随机推荐

  1. PHP的加解密:如何安装ioncube扩展?

    一.下载loader-wizard.php(支持php5.3.php5.4.php5.5.php5.6版本) ioncube提供了一个安装的向导程序,可以非常方便的帮助检测php的运行环境,自动给出提 ...

  2. Ajax经典的面试题

    1.什么是AJAX,为什么要使用Ajax(请谈一下你对Ajax的认识)什么是ajax:AJAX是“Asynchronous JavaScript and XML”的缩写.他是指一种创建交互式网页应用的 ...

  3. React 官方脚手架 create-react-app快速生成新项目

    进入新公司已经半年了,各个业务线,技术栈都已经熟悉,工作也已经游刃有余,决定慢下脚步,沉淀积累,回顾一下所用技术栈所包含的基本知识,以及再公司中的实战. 首先回顾新项目搭建 react脚手架目前使用较 ...

  4. 最大长度回文子串(Manacher's algorithm)

    输出最大长度的回文子串. string longestPalindrome(string s) { int id, mx, i, j, len, maxlen; vector<char> ...

  5. javaweb基础(22)_Servlet+JSP+JavaBean实战登陆

    一.Servlet+JSP+JavaBean开发模式(MVC)介绍 Servlet+JSP+JavaBean模式(MVC)适合开发复杂的web应用,在这种模式下,servlet负责处理用户请求,jsp ...

  6. 遍历Map的两种方式

    取出map集合中所有元素的方式一:keySet()方法. 可以将map集合中的键都取出存放到set集合中.对set集合进行迭代.迭代完成,再通过get方法对获取到的键进行值的获取. Set keySe ...

  7. loj6485 LJJ 学二项式定理

    题目描述: loj 题解: 单位根反演. $[n|x]=\frac{1}{n} \sum _{i=0}^{n-1} (ω_n^x)^i$ 证明?显然啊,要么停在$(1,0)$要么转一圈. 所以说题目要 ...

  8. 小程序电脑调试没有问题,真机预览报错fail hand shake error

    今天在做小程序的过程中使用HTTPS请求数据时,遇到安卓机型无法获取到数据,通过一系列的排查,发现是因为ssl证书的问题,后来通过https://www.myssl.cn/tools/check-se ...

  9. PAT Basic 1077

    1077 互评成绩计算 在浙大的计算机专业课中,经常有互评分组报告这个环节.一个组上台介绍自己的工作,其他组在台下为其表现评分.最后这个组的互评成绩是这样计算的:所有其他组的评分中,去掉一个最高分和一 ...

  10. 通过Proxool配置访问数据库的要点

    proxool 配置的时候有Proxool.properties 或者 Proxool.xml 两种方式初始化. 我的配置环境是 myEclipse10+tomcat6.0 + mysql5.0 . ...