函数式编程
map
#map(f, I) 等价于对I的每个元素I(i)都执行f, 然后再把所有f(I(i))拼接成一个Iterator并返回
#map传入函数和一个Iterable(一个序列),返回一个Iterator
#注意到Iterator是惰性序列,只有被调用才能被获取,要通过诸如list,for等等 迭代出来
def f(x):
return x*x
L = 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+y
print(reduce(add, [1,2,3,4,5]))
print("\n")
def fn(x,y):
return 10*x+y
print(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')
#改进版1
digits = {'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 name
name = ['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]=='.'):
break
print(i) #说明前面有i个数,小数点后面有len(str)-i位,
'''
#写个函数求i
def 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+b
str = "123.456"
print(str2float(str), '\n')