一、map

Python内置函数,用法及说明如下:

  1. class map(object):
  2. """
  3. map(func, *iterables) --> map object
  4.  
  5. Make an iterator that computes the function using arguments from
  6. each of the iterables. Stops when the shortest iterable is exhausted.
  7. """

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

举例说明,比如我们有一个函数f(x)=x2,要把这个函数作用在一个list [1, 2, 3, 4, 5, 6, 7, 8, 9]上,就可以用map()实现如下:

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

map()传入的第一个参数是f,即函数对象本身。由于结果r是一个IteratorIterator是惰性序列,因此通过list()函数让它把整个序列都计算出来并返回一个list。

  1. #使用lambda匿名函数
  2. list(map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
  3. [1, 4, 9, 16, 25, 36, 49, 64, 81]

  

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

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

map函数的优点:

  1. 函数逻辑更加清晰,参数‘f’就表明了对元素的操作
  2. map是高阶函数,可以执行抽象度更高的运算  

二、 reduce

  1. def reduce(function, sequence, initial=None): # real signature unknown; restored from __doc__
  2. """
  3. reduce(function, sequence[, initial]) -> value
  4.  
  5. Apply a function of two arguments cumulatively to the items of a sequence,
  6. from left to right, so as to reduce the sequence to a single value.
  7. For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates
  8. ((((1+2)+3)+4)+5). If initial is present, it is placed before the items
  9. of the sequence in the calculation, and serves as a default when the
  10. sequence is empty.
  11. """
  12. pass

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

  1. reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)

比方说对一个序列求和,就可以用reduce实现:

  1. from functools import reduce
  2. def add(x, y):
  3. return x + y
  4. reduce(add, [1, 3, 5, 7, 9])
  5. 25

匿名函数实现:

  1. reduce(lambda x, y : x + y, [1, 3, 5, 7, 9])
  2. 25

当然求和运算可以直接用Python内建函数sum(),没必要动用reduce

但是如果要把序列[1, 3, 5, 7, 9]变换成整数13579reduce就可以派上用场:

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

匿名函数实现:

  1. reduce(lambda x, y: x * 10 + y, [1, 3, 5, 7, 9])
  2. 13579

这个例子本身没多大用处,但是,如果考虑到字符串str也是一个序列,对上面的例子稍加改动,配合map(),我们就可以写出把str转换为int的函数:

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

整理成一个str2int的函数就是:

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

还可以用lambda函数进一步简化成:

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

小练习:

  1. 利用map()函数,把用户输入的不规范的英文名字,变为首字母大写,其他小写的规范名字。输入:['adam', 'LISA', 'barT'],输出:['Adam', 'Lisa', 'Bart']: 
  1. list(map(lambda x: x.capitalize(), ['adam', 'LISA', 'barT']))
  2. ['Adam', 'Lisa', 'Bart']

  2. Python提供的sum()函数可以接受一个list并求和,请编写一个prod()函数,可以接受一个list并利用reduce()求积:

  1. def prod(l):
  2. return reduce(lambda x, y: x * y, l)
  3. l = [1, 2 ,3, 4, 5]
  4. print(prod(l))
  5. 120

  匿名函数实现:

  1. reduce(lambda x, y: x * y, [1, 2, 3, 4, 5])
  2. 120

  3. 利用mapreduce编写一个str2float函数,把字符串'123.456'转换成浮点数123.456:  

  1. from functools import reduce
  2. def char2num(s):
  3. return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]
  4. def str_split(s):
  5. s1, s2 = s.split('.')
  6. return s1, s2
  7. def str2int_1(s1):
  8. return reduce(lambda x, y: x * 10 + y, map(char2num, s1))
  9. def str2int_2(s2):
  10. return (reduce(lambda x, y: x * 10 + y, map(char2num, s2)))/pow(10, len(s2))
  11. def str2float(s):
  12. s1, s2 = str_split(s)
  13. res = str2int_1(s1) + str2int_2(s2)
  14. return res
  15. a = str2float('123.456')
  16. print(a)
  17. 123.456

  

 三、filter

Python内建的filter()函数用于过滤序列。

map()类似,filter()也接收一个函数和一个序列。和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。

  1. class filter(object):
  2. """
  3. filter(function or None, iterable) --> filter object
  4.  
  5. Return an iterator yielding those items of iterable for which function(item)
  6. is true. If function is None, return the items that are true.
  7. """

例如,在一个list中,删掉偶数,只保留奇数,可以这么写:

  1. def is_odd(n):
  2. return n % 2 == 1
  3. list(filter(is_odd, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
  4. [1, 3, 5, 7, 9]

同样可以加入匿名函数:

  1. list(filter(lambda x: x % 2 == 1, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
  2. [1, 3, 5, 7, 9]

把一个序列中的空字符串删掉,可以这么写:

  1. def not_empty(s):
  2. return s and s.strip()
  3. list(filter(not_empty, ['A', '', 'B', None, 'C', ' ']))
  4. ['A', 'B', 'C']

匿名函数的形式:

  1. list(filter(lambda x: x and x.strip(), ['A', '', 'B', None, 'C', ' ']))
  2. ['A', 'B', 'C']

可见用filter()这个高阶函数,关键在于正确实现一个“筛选”函数。

注意到filter()函数返回的是一个Iterator,也就是一个惰性序列,所以要强迫filter()完成计算结果,需要用list()函数获得所有结果并返回list。

实例:

用filter求素数

计算素数的一个方法是埃氏筛法,它的算法理解起来非常简单:

首先,列出从2开始的所有自然数,构造一个序列:

2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...

取序列的第一个数2,它一定是素数,然后用2把序列的2的倍数筛掉:

3, , 5, , 7, , 9, , 11, , 13, , 15, , 17, , 19, , ...

取新序列的第一个数3,它一定是素数,然后用3把序列的3的倍数筛掉:

5, , 7, , , , 11, , 13, , , , 17, , 19, , ...

取新序列的第一个数5,然后用5把序列的5的倍数筛掉:

7, , , , 11, , 13, , , , 17, , 19, , ...

不断筛下去,就可以得到所有的素数。

用Python来实现这个算法,可以先构造一个从3开始的奇数序列:

  1. def _odd_iter():
  2. n = 1
  3. while True:
  4. n = n + 2
  5. yield n

注意这是一个生成器,并且是一个无限序列。

然后定义一个筛选函数:

  1. def _not_divisible(n):
  2. return lambda x: x % n > 0

最后,定义一个生成器,不断返回下一个素数:

  1. def primes():
  2. yield 2
  3. it = _odd_iter() #初始序列
  4. while True:
  5. n = next(it) #返回序列的第一个数
  6. yield n
  7. it = filter(_n

这个生成器先返回第一个素数2,然后,利用filter()不断产生筛选后的新的序列。

由于primes()也是一个无限序列,所以调用时需要设置一个退出循环的条件:

  1. #打印100以内的素数
  2. for n in primes():
  3. if n < 100:
  4. print(n)
  5. else:
  6. break
  7.  
  8. 2
  9. 3
  10. 5
  11. 7
  12. 11
  13. 13
  14. 17
  15. 19
  16. 23
  17. 29
  18. 31
  19. 37
  20. 41
  21. 43
  22. 47
  23. 53
  24. 59
  25. 61
  26. 67
  27. 71
  28. 73
  29. 79
  30. 83
  31. 89
  32. 97

注意到Iterator是惰性计算的序列,所以我们可以用Python表示“全体自然数”,“全体素数”这样的序列,而代码非常简洁。

小练习:

  1. 回数是指从左向右读和从右向左读都是一样的数,例如12321909。请利用filter()滤掉非回数:
  1. list(filter(lambda x: str(x) == str(x)[::-1], range(1,1000)))
  2. [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, 44, 55, 66, 77, 88, 99, 101, 111, 121, 131, 141, 151, 161, 171, 181, 191, 202, 212, 222, 232, 242, 252, 262, 272, 282, 292,
    303, 313, 323, 333, 343, 353, 363, 373, 383, 393, 404, 414, 424, 434, 444, 454, 464, 474, 484, 494, 505, 515, 525, 535, 545, 555, 565, 575, 585, 595, 606, 616, 626,
    636, 646, 656, 666, 676, 686, 696, 707, 717, 727, 737, 747, 757, 767, 777, 787, 797, 808, 818, 828, 838, 848, 858, 868, 878, 888, 898, 909, 919, 929, 939, 949, 959,
    969, 979, 989, 999]

  思路:先将int数字类型转换为str字符串类型,然后比较原字符串和取反后的字符串是否相等来返回值。

  

  

参考资料:

廖雪峰的官方网站

帮助很大,非常感谢!

  

  

  

  

  

  

  

  

  

  

  

Python基础-map/reduce/filter的更多相关文章

  1. python基础===map, reduce, filter的用法

    filter的用法: 这还是一个操作表list的内嵌函数'filter' 需要一个函数与一个list它用这个函数来决定哪个项应该被放入过滤结果队列中遍历list中的每一个值,输入到这个函数中如果这个函 ...

  2. python基础——map/reduce

    python基础——map/reduce Python内建了map()和reduce()函数. 如果你读过Google的那篇大名鼎鼎的论文“MapReduce: Simplified Data Pro ...

  3. Demo of Python &quot;Map Reduce Filter&quot;

    Here I share with you a demo for python map, reduce and filter functional programming thatowned by m ...

  4. Python: lambda, map, reduce, filter

    在学习python的过程中,lambda的语法时常会使人感到困惑,lambda是什么,为什么要使用lambda,是不是必须使用lambda? 下面就上面的问题进行一下解答. 1.lambda是什么? ...

  5. [python基础知识]python内置函数map/reduce/filter

    python内置函数map/reduce/filter 这三个函数用的顺手了,很cool. filter()函数:filter函数相当于过滤,调用一个bool_func(只返回bool类型数据的方法) ...

  6. python之map、filter、reduce、lambda函数 转

    python之map.filter.reduce.lambda函数  转  http://www.cnblogs.com/kaituorensheng/p/5300340.html 阅读目录 map ...

  7. Python学习:函数式编程(lambda, map() ,reduce() ,filter())

    1. lambda: Python 支持用lambda对简单的功能定义“行内函数” 2.map() : 3.reduce() : 4.filter() : map() ,reduce() , filt ...

  8. python 函数式编程之lambda( ), map( ), reduce( ), filter( )

    lambda( ), map( ), reduce( ), filter( ) 1. lambda( )主要用于“行内函数”: f = lambda x : x + 2 #定义函数f(x)=x+2 g ...

  9. Python map/reduce/filter/sorted函数以及匿名函数

    1. map() 函数的功能: map(f, [x1,x2,x3]) = [f(x1), f(x2), f(x3)] def f(x): return x*x a = map(f, [1, 2, 3, ...

随机推荐

  1. nginx克隆之后问题

    [alert] kill(2942, 1) failed (No such process) 背景:虚拟机克隆之后启动service nginx reload报这个错,而且没有日志 根据这个博文htt ...

  2. python全栈开发_day3_数据类型,输入输出及运算符

    一:常见数据类型 1)int整型 例:age=1 整型常用于年龄,账号等 2)float浮点型 例:salary=5.1 浮点型常用于薪水,身高,体重等 3)str字符串类型 例:name=“chen ...

  3. 数组去重 && 快速排序 && 数组中重复元素最多的 && 深拷贝

    var arr0 = [1,3,3,3,4,4,4,4,5,5]; var arr1 = [10,9,2,5,7,34,65,48,90,103]; var newArr=[]; /* for(var ...

  4. Delphi XE TStringBuilder

    function T_SunnySky_SDK.JoinItems(AParamDic: TDictionary<string, string>): string; var sb : TS ...

  5. 使用BeanUtils封装数据时数据类型的转换

    //获得表单数据 Map<String, String[]> properties = request.getParameterMap(); User user = new User(); ...

  6. unity换装系统+网格合并

    这里的做法是模型把所有衣服全部穿上作为一个资源 然后还有一个只有骨骼信息的骨架资源 将这2个制作好了Prefab 模型部件数据 资源数据 [代码] using System.Collections; ...

  7. 2014年北京网络赛 Instrusive HDU 5040 题解 优先队列

    网赛的时候看了这道题,发现就是平常的那种基础搜索题. 由于加了一个特殊条件:可以一次消耗3秒或原地停留1秒. 那就不能使用简单的队列了,需要使用优先队列才行. 题意 告诉一副地图:一个起点,一个终点, ...

  8. Python基础(3) - 数据类型:5字典类型

    Python Dictionary 是 Python 的内置数据类型之一, 它定义了键和值之间一对一的关系 .它是用{}括起来的.每个Dictionary的项的句法为:key:value. Dicti ...

  9. 有向图和无向图的数组C++实现

    源码:https://github.com/cjy513203427/C_Program_Base/tree/master/55.%E5%9B%BE 结点类Noded.h 不需要存储索引 #pragm ...

  10. [java源码解析]对HashMap源码的分析(一)

    最近有空的时候研究了下HashMap的源码,平时我用HashMap主要拿来当业务数据整理后的容器,一直觉得它比较灵活和好用, 这样 的便利性跟它的组成结构有很大的关系. 直接开门见山,先简要说明一下H ...