写在前面:
map(function, sequence[, sequence, ...]) -> list
map函数的参数为一个函数,和一个序列(或者很多个序列)。map
将传入的函数依次作用到序列的每个元素,并把结果作为新的list返回。
举例说明,比如我们有一个函数f(x)=x2,要把这个函数作用在一个list [1, 2, 3, 4, 5, 6, 7, 8, 9]
上,就可以用map()
实现如下:
def f(x):
return pow(x,2)
queue = [1,2,3,4,5,6,7,8,9]
result = map(f,queue)
从结果上来看,其等价于
def f(x):
return pow(x,2)
queue = [1,2,3,4,5,6,7,8,9]
result = []
for item in queue:
result.append(f(item))
但是map函数相等直观,而且在数据量非常庞大的情况下,map函数具有很大的速度优势。下面我们来看一组例子
#coding=utf-8
import numpy as np
import time
a = np.random.randint(100,size=100000)
b = np.random.randint(100,size=100000)
def f(x,y):
return pow(x,y)
'''不使用map函数,运行时间0.0880000591278s'''
start1 = time.time()
result1 = []
for i in range(len(a)):
result1.append(f(a[i],b[i]))
end1 = time.time()
print end1-start1
'''使用map函数,运行时间0.0420000553131s'''
start2 = time.time()
result2 = map(f,a,b)
end2 = time.time()
print end2-start2
reduce(function, sequence[, initial]) -> value
reduce把一个函数作用在一个序列[x1, x2, x3...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,其效果就是:
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
当然reduce还可以接受一个初始化参数,效果如下,其实就是为了防止输入的列表为空,此时返回initial的值。如果列表不为空,相当于如下效果
reduce(f, [x1,x2],initial=x0) = f(f(x0, x1), x2)
这个函数在处理字符串和整数转换时有很奇妙的用处哦。可以参见廖雪峰老师的博客。
filter(function or None, sequence) -> list, tuple, or string
看名字就知道filter函数是用来过滤数据的。其输入可以是列表,字符串,元组等序列。filter()
也接收一个函数和一个序列,filter()
把传入的函数依次作用于每个元素,然后根据返回值是True
还是False
决定保留还是丢弃该元素。
举个例子,比如我们要筛选"I am 22 years old."中的数字。
import numpy as np
import time
def f(x):
numList = ['0','1','2','3','4','5','6','7','8','9']
if x in numList:
return True
else:
return False
queue = "I am 22 years old."
print filter(f,queue)
执行上面的代码,输出为22.
sorted和上面三个函数都不同,它不是为了处理并行大规模数据产生的,它按照我们自定义的规则对输入的序列进行排序。自定义的比较函数必须遵循,对于两个元素x
和y
,如果认为x < y
,则返回-1
,如果认为x == y
,则返回0
,如果认为x > y
,则返回1
,这样,排序算法就不用关心具体的比较过程,而是根据比较结果直接排序。
sorted(iterable, cmp=None, key=None, reverse=False) --> new sorted list
"""
对一个iterable对象排序,返回一个排序之后的list
@param iterable 可迭代遍历对象
@param cmp 默认None, 自定义的比较函数,2个参数
@param key 默认None, 自定义的函数,1个参数,参数值来源于列表元素,该函数的返回值用来排序
@param reverse 默认False(正序)
@return 返回一个排序之后的list
"""
下面我们举个例子来说明一下,对一个包含姓名和年龄两个属性的对象来按年龄进行排序,[User("James", 30), User("Marvin", 28), User("Parke", 40), User("Li", 40)]。下面我们介绍几种不同的实现方法
方法一:使用key关键字
代码如下,该方法相当于按f(user)的大小进行排序
class User(object):
def __init__(self, name, age):
self.name = name
self.age = age
def __repr__(self):
return repr((self.name, self.age))
def f(item):
return item.age
test_list = [User("James", 30), User("Marvin", 28), User("Parke", 40), User("Li", 40)]
print sorted(test_list,key=f)
执行结果
方法二:自定义比较方法
代码如下,我们自定义了mycmp方法,直接对user使用mycmp函数比大小进行排序。
class User(object):
def __init__(self, name, age):
self.name = name
self.age = age
def __repr__(self):
return repr((self.name, self.age))
def mycmp(item1,item2):
if(item1.ageitem2.age):
return 1
else:
return 0
test_list = [User("James", 30), User("Marvin", 28), User("Parke", 40), User("Li", 40)]
print sorted(test_list,cmp=mycmp)
执行结果:
那么通过key和cmp都可以达到相同的效果,那么为什么设置这两个不同的参数呢,他们有什么区别呢?
总结:真个比大小的完成流程应该是cmp(key(item1),key(item2));也就是key函数以输入序列的元素为输入参数,key的返回值用来作为cmp函数的输入参数。两个函数可以结合使用。