一、背后机理
Python是一种弱类型语言,也就是说,一个Python的变量是可以随时通过赋值来改变数据类型的。这与C,C++这种强类型语言不同。强类型语言一旦声明了数据类型,是不允许再改变的。
在Python中,函数名其实就是指向函数的变量。
例如,如果abs = 10, 那再运行abs(-10)就会引发错误。因为abs已经不是那个指向求绝对值函数的变量了,而是变成了整型变量。
既然,函数名字可以当成一个变量来使用,那么它当然可以当成另一个函数的参数来使用。
这有就给了Python一个机会,创造了一个非常有趣的机制------高阶函数
二、map函数
在将map函数之前,先来个Python的高阶函数热热身。
def add(x, y, f):
return f(x) + f(y)
以上定义了一个高阶函数add。
add的第三个参数是一个函数。add返回的就是利用该函数创造的新数据。
如果在调用的时候如下面程序一样,将abs作为实参传入,就会产生高阶函数的调用效果。
add(-1,-2,abs)
得到的结果为3.
OK!热身完毕。我们正式来认识一下map函数
map函数有两个参数:
分别为:一个函数名和一个Iterable对象(你可以理解为,一个可迭代的对象,如list,tuple,str等)。
map的执行逻辑:
map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回。
我们举例说明:
函数f(x)=x * x ,要把这个函数作用在一个list[1, 2, 3, 4, 5, 6, 7, 8, 9]上。就可以用map()实现如下:
则有:
def f(x):
return x * x
r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
其中。f作为第一个参数,并参与到第二个参数list的每一个元素的运算中,得到最新的值。
这里需要注意,r的值只是得到了一个map对象,实际上是一个Iterator。如果你直接print(r),他返回的是:<map object at 0x00000000021342E8>
那如何才能查看map函数最终包含的那个数据集呢。
1.直接使用构造函数强制转换为一个可迭代数据集。
例如上例中,如果要查看数据,可以使用
print(list(r))
2.由于map函数是一个Iterator,可以使用next方法来缓缓输出结果。
例如上例中,如果要查看数据, 可以使用
print(next(r))
print(next(r))
......
3.可以使用for循环遍历map对象,来获得数据输出。
例如上例中,如果要查看数据,可以使用
for n in r:
print(n)
三、reduce函数
reduce函数和map函数不同,map函数在运行过后,仍然可以得到的是整体变换后的数据集。
reduce函数也有两个参数。
第一个参数是一个函数名,但该函数有个要求,那就是它需要有两个参数,并且返回的是这两个参数经过运算后的一个最终结果。
第二个参数是一个Iterable对象(你可以理解为,一个可迭代的对象,如list,tuple,str等)。
map的执行逻辑:
依次利用第一个参数代表的函数作用在第二个参数的相邻两个元素上,得到的结果作为新的元素再与下一个元素继续结合,最终得到一个值。
举例说明:
把序列[1, 3, 5, 7, 9]变换成整数13579
可以用如下的reduce函数来实现。
from functools import reduce
def fn(x, y):
return x * 10 + y
reduce(fn, [1, 3, 5, 7, 9])
四、一个map/reduce的深化实例
将一个数字字符串转换为真正的数字。
from functools import reduce
def fn(x, y):
return x * 10 + y
def char2num(s):
digits = {‘0’: 0, ‘1’: 1, ‘2’: 2, ‘3’: 3, ‘4’: 4, ‘5’: 5, ‘6’: 6, ‘7’: 7, ‘8’: 8, ‘9': 9}
return digits[s]
reduce(fn, map(char2num, '13579’))
学懂了就点个赞吧。我是瑞哥。