总结:刚接触函数式编程,实际就是函数之间的调用,重点是把我return值。
内容有:map和reduce
1 函数式编程
>>> f = abs
>>> f(-10)
10
说明变量f
现在已经指向了abs
函数本身。直接调用abs()
函数和调用变量f()
完全相同
一个最简单的高阶函数:
def add(x, y, f):
return f(x) + f(y)
编写高阶函数,就是让函数的参数能够接收别的函数。
2 map
map()
函数接收两个参数,一个是函数,一个是Iterable
,map
将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator
返回
>>> def f(x):
... return x * x
...
>>> r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> list(r)
[1, 4, 9, 16, 25, 36, 49, 64, 81]
map()
传入的第一个参数是f
,即函数对象本身。由于结果r
是一个Iterator
,Iterator
是惰性序列,因此通过list()
函数让它把整个序列都计算出来并返回一个list。
我们不但可以计算简单的f(x)=x2,还可以计算任意复杂的函数,比如,把这个list所有数字转为字符串:
>>> list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
['1', '2', '3', '4', '5', '6', '7', '8', '9']
注:即此处str也可看作一个函数
3 reduce
reduce
把一个函数作用在一个序列[x1,
x2, x3, ...]
上,这个函数必须接收两个参数,reduce
把结果继续和序列的下一个元素做累积计算,其效果就是:
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
如果要把序列[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])
13579
如果考虑到字符串str
也是一个序列,对上面的例子稍加改动,配合map()
,我们就可以写出把str
转换为int
的函数:
>>> from functools import reduce
>>> def fn(x, y):
... return x * 10 + y
...
>>> def char2num(s):
... return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]
...
>>> reduce(fn, map(char2num, '13579'))
13579
整理成一个str2int
的函数就是:
from functools import reduce
def str2int(s):
def fn(x, y):
return x * 10 + y
def char2num(s):
return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]
return reduce(fn, map(char2num, s))
也就是说,假设Python没有提供int()
函数,你完全可以自己写一个把字符串转化为整数的函数4
练习①
利用
map()
函数,把用户输入的不规范的英文名字,变为首字母大写,其他小写的规范名字。输入:['adam',
'LISA', 'barT']
,输出:['Adam',
'Lisa', 'Bart']:
def
normalize(name):
return name[0].upper()+name[1:].lower()
L1 = ['adam', 'LISA', 'barT'] L2 = list(map(normalize, L1)) print(L2)
注:此处name里面1:是切片,即可去守卫之后的字母了(切片对各种格式通用),upper和lower记住即可,他们都是字符串函数就是这种用法
5
练习②
编写一个prod()
函数,可以接受一个list并利用reduce()
求积:
from functools import reduce
def prod(L):
def f(x,y):return x*y
return reduce(f,L)
print('3 * 5 * 7 * 9 =', prod([3, 5, 7, 9]))
总算独立完成一个作业。。。
6练习③
利用map和reduce编写一个str2float函数,把字符串'123.456'转换成浮点数123.456
from
functools
import
reduce
def
str2float(s):
return
reduce
(
lambda
x,y:x
+
int2dec(y),
map
(str2int,s.split(
'.'
)))
def
char2num(s):
return
{
'0'
:
0
,
'1'
:
1
,
'2'
:
2
,
'3'
:
3
,
'4'
:
4
,
'5'
:
5
,
'6'
:
6
,
'7'
:
7
,
'8'
:
8
,
'9'
:
9
}[s]
def
str2int(s):
return
reduce
(
lambda
x,y:x
*
10
+
y,
map
(char2num,s))
def
intLen(i):
return
len
(
'%d'
%
i)
def
int2dec(i):
return
i
/
(
10
*
*
intLen(i))
print
(str2float(
'123.456'
))