map 函数
map 是一个在 Python 里非常有用的高阶函数。它接受一个函数和一个序列(迭代器)作为输入,然后对序列(迭代器)的每一个值应用这个函数,返回一个序列(迭代器),其包含应用函数后的结果。
语法
map(function, iterable, ...)
参数iterable可以是一个或多个序列
例子
1、计算平方数
def square(x): return x ** 2 lst = map(square, [1,2,3,4,5]) print(list(lst)) #[1, 4, 9, 16, 25]
使用 lambda 匿名函数
lst2 = map(lambda x:x**2, [1,2,3,4,5]) print(list(lst2)) #[1, 4, 9, 16, 25]
2、提供了两个列表,对相同位置的列表数据进行相加
lst3 = map(lambda x, y: x + y, [1, 3, 5, 7, 9], [2, 4, 6, 8, 10]) print(list(lst3)) #[3, 7, 11, 15, 19]
3、假设用户输入的英文名字不规范,没有按照首字母大写,后续字母小写的规则,请利用map()函数,把一个list(包含若干不规范的英文名字)变成一个包含规范英文名字的list:
输入:['adam', 'LISA', 'barT']
输出:['Adam', 'Lisa', 'Bart']
name_list = ['adam', 'LISA', 'barT'] def format_name(s): return s.lower().capitalize() print(list(map(format_name, name_list)))
或使用匿名函数
print(list(map(lambda x:x.capitalize(), name_list)))
filter函数
filter()函数是 Python 内置的另一个有用的高阶函数,filter()函数接收一个函数 f 和一个list,这个函数 f 的作用是对每个元素进行判断,返回 True或 False,filter()根据判断结果自动过滤掉不符合条件的元素,返回由符合条件元素组成的新list。
例如,要从一个list [1, 4, 6, 7, 9, 12, 17]中删除偶数,保留奇数,首先,要编写一个判断奇数的函数,然后,利用filter()过滤掉偶数:
def is_odd(x): return x % 2 == 1 filter(is_odd, [1, 4, 6, 7, 9, 12, 17]) 结果:[1, 7, 9, 17]
利用filter(),可以完成很多有用的功能,例如,删除 None 或者空字符串:
def is_not_empyt(s): return s and len(s.split()) > 0 newlist = filter(is_not_empyt, ['1', 'str', '', ' ']) print(list(newlist)) ['1', 'str']
关于filter()方法, python3和python2有一点不同
Python2.x 中返回的是过滤后的列表, 而 Python3 中返回到是一个 filter 类。
filter 类实现了 __iter__ 和 __next__ 方法, 可以看成是一个迭代器, 有惰性运算的特性, 相对 Python2.x 提升了性能, 可以节约内存。
a = filter(lambda x: x % 2 == 0, range(10)) print(a) 输出 <filter object at 0x0000022EC66BB128>
所以在python3中输出需要用print(list(a))
例子
请利用filter()过滤出1~100中平方根是整数的数,即结果应该是:
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
filter()接收的函数必须判断出一个数的平方根是否是整数,而math.sqrt()返回结果是浮点数,所以没办法用isinstance判断数据类型是整数
方法一: import math def is_sqr(x): r = int(math.sqrt(x)) return r*r==x print filter(is_sqr, range(1, 101)) 方法二: import math def my_sqrt(x): return math.sqrt(x) % 1 == 0 lst = filter(my_sqrt, range(1,101)) print(list(lst))
reduce函数
reduce()函数也是Python内置的一个高阶函数。reduce()函数接收的参数和 map()类似,一个函数 f,一个list,但行为和 map()不同,reduce()传入的函数 f 必须接收两个参数,reduce()对list的每个元素反复调用函数f,并返回最终结果值。
在python2中可直接使用reduce()函数
在Python3里,reduce()函数已经被从全局名字空间里移除了,它现在被放置在functools模块里,用的话要先引入from functools import reduce
语法
reduce(function, iterable[, initializer])
参数
function -- 函数
iterable -- 可迭代对象
initializer -- 可选,初始参数
例如,编写一个f函数,接收x和y,返回x和y的和:
def f(x, y):
return x + y
调用 reduce(f, [1, 3, 5, 7, 9])时,reduce函数将做如下计算:
先计算头两个元素:f(1, 3),结果为4;
再把结果和第3个元素计算:f(4, 5),结果为9;
再把结果和第4个元素计算:f(9, 7),结果为16;
再把结果和第5个元素计算:f(16, 9),结果为25;
由于没有更多的元素了,计算结束,返回结果25。
上述计算实际上是对 list 的所有元素求和。虽然Python内置了求和函数sum(),但是,利用reduce()求和也很简单。
reduce()还可以接收第3个可选参数,作为计算的初始值。如果把初始值设为100,计算:
reduce(f, [1, 3, 5, 7, 9], 100)
结果将变为125,因为第一轮先计算初始值和第一个元素:f(100, 1),结果为101。
例子
Python内置了求和函数sum(),但没有求积的函数,请利用recude()来求积:
输入:[2, 4, 5, 7, 12]
输出:2*4*5*7*12的结果
lst1 = [2, 4, 5, 7, 12] from functools import reduce def prod(x, y): return x*y print(reduce(prod, lst1))
sorted函数
sorted()也是一个高阶函数,可以接收可迭代对象、比较函数、比较的元素和排序规则
语法:
sorted(iterable[, cmp[, key[, reverse]]])
参数说明:
iterable -- 可迭代对象。
cmp -- 比较的函数,这个具有两个参数,参数的值都是从可迭代对象中取出,此函数必须遵守的规则为,大于则返回1,小于则返回-1,等于则返回0。
key -- 主要是用来进行比较的元素,只有一个参数,具体的函数的参数就是取自于可迭代对象中,指定可迭代对象中的一个元素来进行排序。
reverse -- 排序规则,reverse = True 降序 , reverse = False 升序(默认)。
Python 3.X 的版本中已经没有cmp函数,使用key即可
python2中它可以接收一个比较函数来实现自定义排序,比较函数的定义是,传入两个待比较的元素 x, y,如果 x 应该排在 y 的前面,返回 -1,如果 x 应该排在 y 的后面,返回 1。如果 x 和 y 相等,返回 0。
因此,如果我们要实现倒序排序,只需要编写一个reversed_cmp函数:
def reversed_cmp(x, y): if x > y: return -1 if x < y: return 1 return 0
这样,调用 sorted() 并传入 reversed_cmp 就可以实现倒序排序:
print(sorted([36, 5, 12, 9, 21], cmp = reversed_cmp)) [36, 21, 12, 9, 5]
sorted()函数可以接收一个key函数来实现自定义的排序,例如按绝对值大小排序:
list = [1,3,5,-10,12,-15] result = sorted(list,key=abs) print(result) [1, 3, 5, -10, 12, -15]
reverse=True反向排序
print(sorted([36, 5, 12, 9, 21], reverse=True)) [36, 21, 12, 9, 5]
sorted()也可以对字符串进行排序,字符串默认按照ASCII大小来比较:
print(sorted(['bob', 'about', 'Zoo', 'Credit'])) ['Credit', 'Zoo', 'about', 'bob']
'Zoo'排在'about'之前是因为'Z'的ASCII码比'a'小。
对字符串排序时,有时候忽略大小写排序更符合习惯。利用sorted()高阶函数,实现忽略大小写排序的算法。
a = ['bob', 'about', 'Zoo', 'Credit'] print (sorted(a, key=lambda x:x.upper())) ['about', 'bob', 'Credit', 'Zoo'] a = ['bob', 'about', 'Zoo', 'Credit'] print (sorted(a, key=str.lower)) ['about', 'bob', 'Credit', 'Zoo']
要进行反向排序,不必改动key函数,可以传入第三个参数reverse=True:
print(sorted(a, key=str.lower, reverse=True)) ['Zoo', 'Credit', 'bob', 'about']
python2中可以利用cmp函数
L=[('b',2),('a',1),('c',3),('d',4)] print sorted(L, cmp=lambda x,y:cmp(x[1],y[1])) [('a', 1), ('b', 2), ('c', 3), ('d', 4)]
利用key
print(sorted(L, key=lambda x:x[1])) [('a', 1), ('b', 2), ('c', 3), ('d', 4)]
按年龄排序
students = [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)] print(sorted(students, key=lambda s: s[2])) [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
按降序
print(sorted(students, key=lambda s: s[2], reverse=True)) [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
匿名函数
python使用lambda来创建匿名函数。lambda只是一个表达式,函数体比def简单很多。
lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑。
lambda函数拥有自己的命名空间,且不能访问自有参数列表之外或全局命名空间里的参数。
虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。
语法
lambda [arg1 [,arg2,.....argn]]:expression
lambda a:b,其中a表示参数,b表示返回值。
以下代码能运行吗? l = [1,2,3,4,5] for i in range(0,len(l)): print i if l[i] % 2 == 0: del l[i] print l 结果: [python] view plain copy Traceback (most recent call last): File "D:1.py", line 3, in <module> if l[i] % 2 == 0: IndexError: list index out of range
因为随着del()语句的执行,list的元素越来越少,但是for已经定了[0,5):
i = 0,l[i] = 1不是偶数跳过
i = 1,l[i] = 2是偶数,l = [1,3,4,5]
i = 2,l[i] = 4是偶数,l=[1,3,5]
i = 3,l[i] 越界了,list index out of range。
以下代码能运行吗? [python] view plain copy ll = [1,2,3,4,5] for i in ll: if i % 2 == 0: ll.remove(i) print ll 结果:[1, 3, 5]
这段代码就没上述的问题。list有多少就取多少。
用filter()和lambda实现上面的功能:
print(list(filter(lambda x:x%2==0,range(10)))) [0, 2, 4, 6, 8]
filter(function,list),把list中的元素一个个丢到function中,Return True的元素组成一个new list。
ll = [1,2,3,4,5] def func(x): return x % 2 != 0 print filter(func,ll)
总结:
1、循环list的时候,最好用for i in list:,减少因为del()犯下不易察觉的失误。
2、在python2 中直接打印map,filter函数会直接输出结果。但在python3中做了些修改,输出前需要使用list()进行显示转换。
3、lambda可以处理的最复杂的情况就是三元运算了,不能再复杂了,比如for循环之类的就不能实现了。
filter()根据判断结果自动过滤掉不符合条件的元素,返回由符合条件元素组成的list。
print(list(filter(fun,ll))) print(list(filter(lambda i:i%2!=0,ll)))
关键字lambda表示匿名函数,冒号前面的x表示函数参数。
匿名函数有个限制,就是只能有一个表达式,不用写return,返回值就是该表达式的结果。
用匿名函数有个好处,因为函数没有名字,不必担心函数名冲突。此外,匿名函数也是一个函数对象,也可以把匿名函数赋值给一个变量,再利用变量来调用该函数:
>>> f = lambda x: x * x >>> f <function <lambda> at 0x101c6ef28> >>> f(5) 25
也可以传入多个参数
计算n的y次方
calc = lambda n,y:n**y print(calc(2,10))