1、map简介:
map 函数一次接收两个参数,一个是函数一个是Iterable,并将传入的函数作用于Iterable,由于结果是一个Iterator,我们直接用list()返回整个序列为list。
#先定义一个函数:
def f(x):
return x * x
r = map(f,[1,2,3,4,5])
#map 依次作用list于f函数,所以他是一个Iterator。
print(list(r))
2、利用map直接将整数转换为str:
print(list(map(str,[1,2,3,4,5,6,7,8])))
结果:
['1', '2', '3', '4', '5', '6', '7', '8']
练习
利用map()函数,把用户输入的不规范的英文名字,变为首字母大写,其他小写的规范名字。输入:[‘adam’, ‘LISA’, ‘barT’],输出:[‘Adam’, ‘Lisa’, ‘Bart’]:
from functools import reduce
def normalize(name):
s = name.lower() #将传入的name参数序列全部小写.
b = s.capitalize()#利用首字母大写函数capitalize
return b
L1 = ['adam', 'LISA', 'barT','JASon']
L2 = list(map(normalize, L1))
print(L2)
2. reduce函数
reduce,即函数套函数,reduce必须接收两个函数,reduce将结果与序列的下一个元素做累积计算。
格式:
reduce(f,[x1,x2,x3])=f(f(x1,x2),x3)
from functools import reduce
def add(x,y):
return x + y
print(reduce(add,[1,2,3]))
from functools import reduce
def fn(x,y):
return x * 10 + y
示例:将字符串’12345’转换为整数12345。
from functools import reduce
def str2int(s):
def fn (x,y):
return x * 10 + y
#必选参数,将x,y转化为10进制数
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))
#这是一个字典取值的写法,{‘0’:0,’1’:1}这是一个字典”key-value”,对应的s为key,当s=’01’时,’01’字符串就对应字典中value的值为01。
print(str2int('12345'))
3、sorted函数
数字的大小我们可以直接比较,而字符串或者序列呢,这时单纯的数学思想是没有用的,就需要利用函数抽象出来.
Python内置的sorted函数就可以对list进行排序:
print(sorted([22,36,5,12,34]))
既然是高阶函数那作用肯定不止于此,sorted函数还支持接收一个Key函数来对序列进行作用。
例如进行绝对值的排序:
print(sorted([-22,36,-5,12,34],key = abs))
结果:
[-5, 12, -22, 34, 36]
#显示的是谁的绝对值大,谁就在后面
字符串也可以用sorted排序:
print( sorted(['bob', 'about', 'Zoo', 'Credit']))
结果:
['Credit', 'Zoo', 'about', 'bob']
为什么会出现这个结果,因为在ASCII编码中,A>a。
这时我们可以改下需求,我们将排序无视大小写。
代码如下:
print( sorted(['bob', 'about', 'Zoo', 'Credit'],key = str.lower))
#无需做多的改动只需要一个key函数即可
结果:
['about', 'bob', 'Credit', 'Zoo']
另一个需求,我们想反向排序怎么办,也就是Z到a。
print( sorted(['bob', 'about', 'Zoo', 'Credit'],key = str.lower,reverse=True))
#只需要传入第三个参数,reverse = (#reverse反转)
结果:
['Zoo', 'Credit', 'bob', 'about']
练习
假设我们用一组tuple表示学生名字和成绩:
L = [(‘Bob’, 75), (‘Adam’, 92), (‘Bart’, 66), (‘Lisa’, 88)]
请用sorted()对上述列表分别按名字排序:
L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]
def by_name(t):
return t[0]
print(sorted(map(by_name,L)))
#将姓名取出来进行排序,复习map知识。
print(sorted(L,key=by_name))
结果:
['Adam', 'Bart', 'Bob', 'Lisa']
[('Adam', 92), ('Bart', 66), ('Bob', 75), ('Lisa', 88)]
请用sorted()对上述列表分别按成绩有大到小排序:
L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]
def by_score(t):
return t[1]
print(sorted(L,key=by_core,reverse = True)
结果:
[('Adam', 92), ('Lisa', 88), ('Bob', 75), ('Bart', 66)]
4、返回函数
返回函数即将函数作为一个返回值。
普通求和函数定义:
def sum1(*args):
x = 0
for s in args:
x = x + s
return x
print(sum1(1,2,3,4,))
返回求和函数sum,你会发现并没有返回和:
def lazy_sum(*args):
def sum():
#定义一个sum函数,并且可以引用lazy_sum的形参和变量。
x = 0
for s in args:
x = x + s
return x
return sum
#返回sum的时候参数和变量都保存在sum里,这种情况称为闭包。
print(lazy_sum(1,2,3,4,))
#结果直接返回了一个sum函数:
<function lazy_sum.<locals>.sum at 0x000001EDC21CDE18>
f = lazy_sum(1,2,3,4,)
#当调用函数f别名时才会出现结果sum的结果。
print(f())
结果:
10
还有一个需要注意的问题就是,上一个例子中,sum函数引用了args局部变量,然后被返回的时候参数和变量都保存在sum里,这种情况称为闭包,所以变量还在被引用新函数(sum)。
def count():
fs = []
for i in range(1, 4):
def f():
return i*i
fs.append(f)
return fs
f1, f2, f3 = count()
#匿名函数
print(f1(),f2(),f3())
在上面的例子中,每次循环,都创建了一个新的函数,然后,把创建的3个函数都返回了。
你可能认为调用f1(),f2()和f3()结果应该是1,4,9,但实际结果是:
9 9 9
为什么呢?因为在返回的时候函数并没有被执行,变量i从1,2变成3。当函数被执行时,结果自然而然就是9了。
如果一定要引用循环变量怎么办?方法是再创建一个函数,用该函数的参数绑定循环变量当前的值,无论该循环变量后续如何更改,已绑定到函数参数的值不变:
def count():
def f(j):
def g():
return j*j
return g
fs = []
for i in range(1, 4):
fs.append(f(i)) # f(i)立刻被执行,因此i的当前值被传入f()
return fs
5、匿名函数
使用匿名函数就不用显式的定义函数,直接传入Lambda会更加方便。还是以map()函数为例,计算f(x)=x*2时,除了定义一个f(x)的函数外,还可以直接传入匿名函数
print(list(map(lambda x : x * x,[1,2,3,4,5] )))
结果:
[1, 4, 9, 16, 25]
通过对比可以看出,匿名函数lambda x: x * x实际上就是:
def f(x):
return x * x
匿名函数有个限制,就是只有一个表达式,不用去写return,表达式就是return的返回值。
我们也可以将lambda作为返回值返回。
例:
def build(x, y):
return lambda: x * x + y * y
print(build(2,3))
f = build(2,3)
print(f())
结果:
<function build.<locals>.<lambda> at 0x00000272BEE4DD90>
13