filter
filter(...) filter(function or None, sequence) -> list, tuple, or string
说明:
对sequence中的item依次执行function(item),将执行结果为True(!=0)的item组成一个List/String/Tuple(取决于sequence的类型)返回,False则退出(0),进行过滤。
例子
>>> def div(n):return n%2 ... >>> filter(div,range(5)) #返回div输出的不等于0的真值 [1, 3] >>> filter(div,range(10)) [1, 3, 5, 7, 9] >>> filter(lambda x : x%2,range(10)) #lambda 函数返回奇数,返回列表 [1, 3, 5, 7, 9] >>> filter(lambda x : not x%2,range(10)) [0, 2, 4, 6, 8] >>> def fin(n):return n!='z' #过滤'z' 函数,出现z则返回False ... >>> filter(fin,'zhoujy') #'z'被过滤 'houjy' >>> filter(lambda x : x !='z','zhoujy') #labmda返回True值 'houjy' >>> filter(lambda x : not x=='z','zhoujy') #返回:字符串 'houjy'
filter()函数接收一个函数 f 和一个list,这个函数 f 的作用是对每个元素进行判断,返回 True或 False,filter()根据判断结果自动过滤掉不符合条件的元素,返回由符合条件元素组成的新list。
例如,要从一个list [1, 4, 6, 7, 9, 12, 17]中删除偶数,保留奇数,首先,要编写一个判断奇数的函数:
def is_odd(x):
return x % 2 == 1
然后,利用filter()过滤掉偶数:
>>>filter(is_odd, [1, 4, 6, 7, 9, 12, 17])
结果:
[1, 7, 9, 17]
利用filter(),可以完成很多有用的功能,例如,删除 None 或者空字符串:
def is_not_empty(s):
return s and len(s.strip()) > 0
>>>filter(is_not_empty, ['test', None, '', 'str', ' ', 'END'])
结果:
['test', 'str', 'END']
注意: s.strip(rm) 删除 s 字符串中开头、结尾处的 rm 序列的字符。
当rm为空时,默认删除空白符(包括' ', ' ', ' ', ' '),如下:
>>> a = ' 123'
>>> a.strip()
'123'
>>> a = ' 123
'
>>> a.strip()
'123'
练习:
请利用filter()过滤出1~100中平方根是整数的数,即结果应该是:
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
方法:
import math
def is_sqr(x):
return math.sqrt(x) % 1 == 0
print filter(is_sqr, range(1, 101))
结果:
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
filter filter为“过滤”、“筛选”之意。指数组filter后,返回过滤后的新数组。用法跟map极为相似: array.filter(callback,[ thisObject]); filter的callback函数需要返回布尔值true或false. 如果为true则表示,恭喜你,通过啦!如果为false, 只能高歌“我只能无情地将你抛弃……”。 可能会疑问,一定要是Boolean值吗?我们可以简单测试下嘛,如下: var data = [0, 1, 2, 3]; var arrayFilter = data.filter(function(item) { return item; }); console.log(arrayFilter); // [1, 2, 3] 有此可见,返回值只要是弱等于== true/false就可以了,而非非得返回 === true/false. 因此,我们在为低版本浏览器扩展时候,无需关心是否返回值是否是纯粹布尔值(见下黑色代码部分): if (typeof Array.prototype.filter != "function") { Array.prototype.filter = function (fn, context) { var arr = []; if (typeof fn === "function") { for (var k = 0, length = this.length; k < length; k++) { fn.call(context, this[k], k, this) && arr.push(this[k]); } } return arr; }; } 接着上面map筛选邮件的例子,您可以狠狠地点击这里:兼容处理后filter方法测试demo 主要测试代码为: var emailsZhang = users // 获得邮件 .map(function (user) { return user.email; }) // 筛选出zhang开头的邮件 .filter(function(email) { return /^zhang/.test(email); }); console.log(emailsZhang.join(", ")); // zhang@email.com filter demo页面的结果截图 张鑫旭-鑫空间-鑫生活 实际上,存在一些语法糖可以实现map+filter的效果,被称之为“数组简约式(Array comprehensions)”。目前,仅FireFox浏览器可以实现,展示下又不会怀孕: var zhangEmails = [user.email for each (user in users) if (/^zhang/.test(user.email)) ]; console.log(zhangEmails); // [zhang@email.com]
map
map(...)
map(function, sequence[, sequence, ...]) -> list
Python中的map函数应用于每一个可迭代的项,返回的是一个结果list。如果有其他的可迭代参数传进来,map函数则会把每一个参数都以相应的处理函数进行迭代处理。map()函数接收两个参数,一个是函数,一个是序列,map将传入的函数依次作用到序列的每个元素,并把结果作为新的list返回。
有一个list, L = [1,2,3,4,5,6,7,8],我们要将f(x)=x^2作用于这个list上,那么我们可以使用map函数处理。
>>> L = [1,2,3,4,] >>> def pow2(x): ... return x*x ... >>> map(pow2,L) [1, 4, 9, 16]
说明:
对sequence中的item依次执行function(item),执行结果输出为list。
例子:
>>> map(str, range(5)) #对range(5)各项进行str操作 ['0', '1', '2', '3', '4'] #返回列表 >>> def add(n):return n+n ... >>> map(add, range(5)) #对range(5)各项进行add操作 [0, 2, 4, 6, 8] >>> map(lambda x:x+x,range(5)) #lambda 函数,各项+本身 [0, 2, 4, 6, 8] >>> map(lambda x:x+1,range(10)) #lambda 函数,各项+1 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] >>> map(add,'zhoujy') ['zz', 'hh', 'oo', 'uu', 'jj', 'yy'] #想要输入多个序列,需要支持多个参数的函数,注意的是各序列的长度必须一样,否则报错: >>> def add(x,y):return x+y ... >>> map(add,'zhoujy','Python') ['zP', 'hy', 'ot', 'uh', 'jo', 'yn'] >>> def add(x,y,z):return x+y+z ... >>> map(add,'zhoujy','Python','test') #'test'的长度比其他2个小 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: add() takes exactly 2 arguments (3 given) >>> map(add,'zhoujy','Python','testop') ['zPt', 'hye', 'ots', 'uht', 'joo', 'ynp']
JS中使用map方法
map方法的作用不难理解,“映射”嘛,也就是原数组被“映射”成对应新数组。下面这个例子是数值项求平方: var data = [1, 2, 3, 4]; var arrayOfSquares = data.map(function (item) { return item * item; }); alert(arrayOfSquares); // 1, 4, 9, 16 callback需要有return值,如果没有,就像下面这样: var data = [1, 2, 3, 4]; var arrayOfSquares = data.map(function() {}); arrayOfSquares.forEach(console.log); 结果如下图,可以看到,数组所有项都被映射成了undefined:
上面的操作如下图
在实际使用的时候,我们可以利用map方法方便获得对象数组中的特定属性值们。例如下面这个例子(之后的兼容demo也是该例子): var users = [ {name: "张含韵", "email": "zhang@email.com"}, {name: "江一燕", "email": "jiang@email.com"}, {name: "李小璐", "email": "li@email.com"} ]; var emails = users.map(function (user) { return user.email; }); console.log(emails.join(", ")); // zhang@email.com, jiang@email.com, li@email.com
Reduce
reduce(...)
reduce(function, sequence[, initial]) -> value
说明:
对sequence中的item顺序迭代调用function,函数必须要有2个参数。要是有第3个参数,则表示初始值,可以继续调用初始值,返回一个值。
例子:
>>> def add(x,y):return x+y ... >>> reduce(add,range(10)) #1+2+3+...+9 45 >>> reduce(add,range(11)) #1+2+3+...+10 55 >>> reduce(lambda x,y:x*y,range(1,3),5) #lambda 函数,5是初始值, 1*2*5 10 >>> reduce(lambda x,y:x*y,range(1,6)) #阶乘,1*2*3*4*5 120 >>> reduce(lambda x,y:x*y,range(1,6),3) #初始值3,结果再*3 360 >>> reduce(lambda x,y:x+y,[1,2,3,4,5,6]) #1+2+3+4+5+6 21
应用map,reduce,filter
1):实现5!+4!+3!+2!+1!
#!/usr/bin/env python #-*- coding:utf-8 -*- def add_factorial(n): empty_list=[] #声明一个空列表,存各个阶乘的结果,方便这些结果相加 for i in map(lambda x:x+1,range(n)): #用传进来的变量(n)来生成一个列表,用map让列表都+1,eg:range(5) => [1,2,3,4,5] a=reduce(lambda x,y:x*y,map(lambda x:x+1,range(i))) #生成阶乘,用map去掉列表中的0 empty_list.append(a) #把阶乘结果append到空的列表中 return empty_list if __name__ == '__main__': import sys #2选1 #(一) try: n = input("Enter a Number(int) : ") result=add_factorial(n) #传入变量 print reduce(lambda x,y:x+y,result) #阶乘结果相加 except (NameError,TypeError): print "That's not a Number!" #(二) # result = add_factorial(int(sys.argv[1])) #传入变量 # print reduce(lambda x,y:x+y,result) #阶乘结果相加
结果:
zhoujy@zhoujy:~/桌面/Python/4$ python factorial.py Enter a Number(int) : 1 1 zhoujy@zhoujy:~/桌面/Python/4$ python factorial.py Enter a Number(int) : 2 3 zhoujy@zhoujy:~/桌面/Python/4$ python factorial.py Enter a Number(int) : 3 9 zhoujy@zhoujy:~/桌面/Python/4$ python factorial.py Enter a Number(int) : 4 33 zhoujy@zhoujy:~/桌面/Python/4$ python factorial.py Enter a Number(int) : 5 153 zhoujy@zhoujy:~/桌面/Python/4$
2):将100~200以内的质数挑选出来
思路:
质数是指:只有1和它本身两个因数,如2、3、5、7都是质数,即能被1和本身整除,1不是质数。
比如一个数字N,看它是否质数的话,就要看:有没有能整除【2,N】之间的数X(不包含本身),即N%X是否为0,要是没有就为质数。
所以我们要实现的算法是:拿一个数字N,去除以【2,N】之间的数X,来得到质数,即:N/2,N/3,……,N/N-2,N/N-1 ===> N/range(2,N)
#!/usr/bin/env python #-*- coding:utf-8 -*- def is_prime(start,stop): stop = stop+1 #包含列表右边的值 prime = filter(lambda x : not [x%i for i in range(2,x) if x%i == 0],range(start,stop)) #取出质数,x从range(start,stop) 取的数 print prime if __name__ == '__main__': try : start = input("Enter a start Number :") except : start = 2 #开始值默认2 try : stop = input("Enter a stop Number :") except : stop = 0 #停止数,默认0,即不返回任何值 is_prime(start,stop)
结果:
zhoujy@zhoujy:~/桌面/Python/4$ python prime.py Enter a start Number : Enter a stop Number :10 [2, 3, 5, 7] zhoujy@zhoujy:~/桌面/Python/4$ python prime.py Enter a start Number :10 Enter a stop Number :20 [11, 13, 17, 19] zhoujy@zhoujy:~/桌面/Python/4$ python prime.py Enter a start Number : Enter a stop Number : []