函数式编程
map
#map(f, I) 等价于对I的每个元素I(i)都执行f, 然后再把所有f(I(i))拼接成一个Iterator并返回#map传入函数和一个Iterable(一个序列),返回一个Iterator#注意到Iterator是惰性序列,只有被调用才能被获取,要通过诸如list,for等等 迭代出来def f(x): return x*xL = list(map(f, [1, 2, 3, 4])) print(L)L2 = list(map(str, L)) #把数字转化成数字字符串print(L2)
reduce
有个小特点:map和filter都是返回一个Iterator,而唯有reduce返回一个{非Iterator}的Iterable
# reduce(f,[x1,x2,x3,x4]) 等价于 f(f(f(x1,x2),x3),x4)# reduce接收一个函数和Iterable,返回一个非Iterator的Iterable对象{非惰性序列}from functools import reduce #reduce在functools模块,要先导入def add(x,y): return x+yprint(reduce(add, [1,2,3,4,5]))print("\n")def fn(x,y): return 10*x+yprint(reduce(fn, [1,2,3,4,5]))print('\n')
map+reduce 把str转化成int
def char2num(c): digits = {'0':0, '1':1, '2':2, '3':3, '4':4, \ '5':5, '6':6, '7':7, '8':8, '9':9} return digits[c]num = reduce(fn, map(char2num, "123456"))print(num,'\n')#改进版1digits = {'0':0, '1':1, '2':2, '3':3, '4':4, \ '5':5, '6':6, '7':7, '8':8, '9':9}def str2num(str): def fn(x,y): return x*10+y def char2num(c): return digits[c] return reduce(fn, map(char2num, str))print(str2num("1234567890"), '\n')#lamda简化版#前面已经定义过digits和char2num,此处不定义fn,而是把fn,直接用lamda表达式来替代def str2num_2(str): return reduce(lambda x,y: x*10+y, map(char2num, str)) #return reduce(lambda x,y: x*10+y, map(lambda c: digits[c], str)) #把char2num也用lamda表达式简化print(str2num_2("456789"), '\n')#print("a".upper())#lamda x: x.upper() 字母变大写
写廖晓峰的三个作业
#1.用map把name中的各个名字标准化:首字母大写,其余字母小写#'''#最开始的尝试,失败def name2stander(name): #return map(lambda x,y: x.upper(),y.lower(), name[:][0], name[:][1:]) #map(lambda x: x.upper(), name[:][0]) #map(lambda y: y.lower(), name[:][1:]) return namename = ['haO', 'ZhaN', 'HangZHOU']#print(name[0][0])print(name)print(name[:])print(list(name[:][0]))#print(name2stander(name), '\n')'''#后来成功的尝试def fup(str): return str[0].upper()+str[1:].lower()#print(fup("aBcDh"))#上面的fup可以用这个代替:lambda str: str[0].upper()+str[1:].lower()def name2stander(name): return list(map(fup, name))name = ['haO', 'ZhaNG', 'HangZHOU']print(name2stander(name), '\n')#对上一个版本进行lambda优化{基本是完美版}def n2s(name): return list(map((lambda str: (str[0].upper()+str[1:].lower())), name))name2 = ['zHAng', 'haO', 'ZHEjianG']print(n2s(name2))print('\n')##########作业2###########################################传入一个list,利用reduce求积def prod(list): return reduce((lambda x,y: x*y), list) Li = [1, 5, 7, 2]print(prod(Li), '\n')##########作业3###########################################利用map和reduce,把"123.456"转化成123.456#测试下123.456的处理str = "123.456"digits = {'0':0, '1':1, '2':2, '3':3, '4':4, \ '5':5, '6':6, '7':7, '8':8, '9':9}'''for i in range(len(str)): if (str[i]=='.'): breakprint(i) #说明前面有i个数,小数点后面有len(str)-i位,'''#写个函数求idef GetDotRank(str): for i in range(len(str)): if (str[i] == '.'): return i#map的功能就是把'123.456'转化成[1,2,3,4,5,6],再分成两个list[1,2,3]与[6,5,4,0]L = list(map((lambda x: digits[x] if (x!='.') else 0), str))print(L, '\n')DotRank = GetDotRank(str)print(DotRank,'\n')L1,L2 = L[0:DotRank], L[-1:DotRank-1:-1] #[lo:hi:step]等价于[lo, hi),步长为step{1为默认,其余步长比如-1均不可以省略}print(L1,'\n', L2, '\n')#小数点前面的reduce(lambda x,y: 10*x+y, [1, 2, 3])a = reduce((lambda x,y: 10*x+y), L1)#小数点后面的reduce(lambda x,y: 0.1*x+y, [6, 5, 4,0])b = reduce((lambda x,y: 0.1*x+y), L2)#再把两者相加print(a, b, a+b,'\n')#############最后定义个str2float解决这个问题####################digits = {'0':0, '1':1, '2':2, '3':3, '4':4, \ '5':5, '6':6, '7':7, '8':8, '9':9}def str2float(str): def GetDotRank(str): for i in range(len(str)): if (str[i] == '.'): return i L = list(map((lambda x: digits[x] if (x!='.') else 0), str)) L1,L2 = L[0:GetDotRank(str)], L[-1:(GetDotRank(str)-1):-1] #[lo:hi:step]等价于[lo, hi),步长为step a = reduce((lambda x,y: 10*x+y), L1) b = reduce((lambda x,y: 0.1*x+y), L2) return a+bstr = "123.456"print(str2float(str), '\n')