python内置函数map/reduce/filter

 

Python中有很多函数式编程的方法,本文介绍的是最常见的几个函数

python有几个内置的函数很有意思:map/filter/reduce,都是对一个集合进行处理,filter很容易理解用于过滤,map用于映射,reduce用于归并.
是python列表方法的三架马车。

1 使用%来格式字符串

注:本文基于python2.7.不同的版本可能会导致差异

  • filter() 函数:
    filter函数的功能相当于过滤器。调用一个布尔函数bool_func来迭代遍历每个seq中的元素;返回一个使bool_seq返回值为true的元素的序列。
    >>>a=[1,2,3,4,5,6,7]
    >>>b=filter(lambda x:x>5,
    a)
    >>>print b
    >>>[6,7]

    如果filter参数值为None,就使用identity()函数,list参数中所有为假的元素都将被删除。如下所示:
    >>>a=[0,1,2,3,4,5,6,7]
    >>>b=filter(None, a)
    >>>print b
    >>>[1,2,3,4,5,6,7]

print(“hello %s : %s” % (“AAA”, “you are so nice”))

Zip – 集资

  • map() 函数:

 

标准格式zip(seq[, seq[, seq]]澳门新葡萄京官网首页,)

style=”FONT-SIZE: small”>map函数func作用于给定序列的每个元素,并用一个列表来提供返回值。

>>> style=”COLOR: #24909d”>map( style=”COLOR: #6ab825; FONT-WEIGHT: bold”>lambda style=”COLOR: #d0d0d0″>x style=”COLOR: #d0d0d0″>: style=”COLOR: #d0d0d0″>x style=”COLOR: #d0d0d0″>+ style=”COLOR: #3677a9″>3,
a) style=”FONT-STYLE: italic; COLOR: #999999″>#这里的a同上
>>> style=”COLOR: #d0d0d0″>[ style=”COLOR: #3677a9″>3 style=”COLOR: #d0d0d0″>, style=”COLOR: #3677a9″>4 style=”COLOR: #d0d0d0″>, style=”COLOR: #3677a9″>5 style=”COLOR: #d0d0d0″>, style=”COLOR: #3677a9″>6 style=”COLOR: #d0d0d0″>, style=”COLOR: #3677a9″>7 style=”COLOR: #d0d0d0″>, style=”COLOR: #3677a9″>8 style=”COLOR: #d0d0d0″>, style=”COLOR: #3677a9″>9 style=”COLOR: #d0d0d0″>, style=”COLOR: #3677a9″>10 style=”COLOR: #d0d0d0″>]

#另一个例子
>>> style=”COLOR: #d0d0d0″>a style=”COLOR: #d0d0d0″>= style=”COLOR: #d0d0d0″>[ style=”COLOR: #3677a9″>1 style=”COLOR: #d0d0d0″>, style=”COLOR: #3677a9″>2 style=”COLOR: #d0d0d0″>, style=”COLOR: #3677a9″>3 style=”COLOR: #d0d0d0″>]
>>>b style=”COLOR: #d0d0d0″>= style=”COLOR: #d0d0d0″>[ style=”COLOR: #3677a9″>4 style=”COLOR: #d0d0d0″>, style=”COLOR: #3677a9″>5 style=”COLOR: #d0d0d0″>, style=”COLOR: #3677a9″>6 style=”COLOR: #d0d0d0″>]
>>> style=”COLOR: #24909d”>map( style=”COLOR: #6ab825; FONT-WEIGHT: bold”>lambda style=”COLOR: #d0d0d0″>x style=”COLOR: #d0d0d0″>, style=”COLOR: #d0d0d0″>y style=”COLOR: #d0d0d0″>: style=”COLOR: #d0d0d0″>x style=”COLOR: #d0d0d0″>+ style=”COLOR: #d0d0d0″>y,
a style=”COLOR: #d0d0d0″>,b)
>>> style=”COLOR: #d0d0d0″>[ style=”COLOR: #3677a9″>5 style=”COLOR: #d0d0d0″>, style=”COLOR: #3677a9″>7 style=”COLOR: #d0d0d0″>, style=”COLOR: #3677a9″>9 style=”COLOR: #d0d0d0″>]

2 使用zip来将两个list构造为一个dict

举个栗子:

  • reduce() 函数:

names = [‘jianpx’, ‘yue’]   
ages = [23, 40]   
m = dict(zip(names,ages)) 
print (m)

a = (i for i in range(3))
b = [4, 5, 6]
c = (7, 8, 9)
abc = zip(a, b, c)

style=”FONT-SIZE: small”>reduce函数,func为二元函数,将func作用于seq序列的元素,每次携带一对(先前的结果以及下一个序列的元素),连续的将现有的结果和下一个值作用在获得的随后的结果上,最后减少我们的序列为一个单一的返回值。

>>> style=”COLOR: #d0d0d0″>a =
[ style=”COLOR: #3677a9″>1 style=”COLOR: #d0d0d0″>, style=”COLOR: #3677a9″>2 style=”COLOR: #d0d0d0″>, style=”COLOR: #3677a9″>3 style=”COLOR: #d0d0d0″>, style=”COLOR: #3677a9″>4 style=”COLOR: #d0d0d0″>, style=”COLOR: #3677a9″>5 style=”COLOR: #d0d0d0″>]
>>> style=”COLOR: #24909d”>reduce( style=”COLOR: #6ab825; FONT-WEIGHT: bold”>lambda style=”COLOR: #d0d0d0″>x style=”COLOR: #d0d0d0″>, style=”COLOR: #d0d0d0″>y style=”COLOR: #d0d0d0″>: style=”COLOR: #d0d0d0″>x style=”COLOR: #d0d0d0″>+ style=”COLOR: #d0d0d0″>y style=”COLOR: #d0d0d0″>, style=”COLOR: #d0d0d0″>a)
15

 

abc的结果为[(0, 4, 7), (1, 5, 8), (2, 6, 9)]

3 不使用临时变量来交换两个值

所以zip函数的作用已经很明显了,它就好比abc三家集资,一家出一个.
那当c家很富,a家没那么富怎么办呢?

a,b = b,a

a = (i for i in range(2))
b = [4, 5, 6]
c = (7, 8, 9, 10)
abc = zip(a,b,c)

 

abc三家集资的结果为[(0, 4, 7), (1, 5,
8)],说好的一家出一个,你家没有了,那我也就不出了(你看,代码也这么现实…)
之所以举的栗子不全是list,就是想说明一个小的注意点,zip接受的都是具有迭代的属性的参数(__iter__),这个后面会讲
Filter – 审查

4 使用str.join来连接字符串

标准格式filter(func, seq)

fruits = [‘apple’, ‘banana’]   
result = ”.join(fruits) 

举个栗子:

 

a = [1, 2, 3]
b = [4, 5, 6]
c = [7, 8, 9]
result = filter(lambda x:sum(x)>14, [a, b, c])
result为[[4, 5, 6], [7, 8, 9]]

5 使用in dict.keys()来判断dict中是否包含指定的key

现在有一个项目,但是这个项目要有个资产审查,要求资产满足lambda标准的企业才有资格参加招标(func是一个bool类型的函数)
Map – 招标

d = {1:”v1″, 2:”v2″}
if 1 in d.keys():
  print(“d dict has the key 1”)

标准格式map(func, seq[, seq[, seq]])

 

举个栗子:

6 使用set来去除list中的重复元素

a = (i for i in range(3))
b = [4, 5, 6]
c = (7, 8, 9)
abc = map(lambda x,y,z: x+y+z, a, b, c)

l = [1,2,2,3]
l2 = set(l)
print(l2)

abc的结果为[11, 14, 17]

 

还是这个招标的项目lambda函数需要招三家(函数的参数个数)来参与这个项目,这个项目分前中后三期的投入.
假如abc三家幸运的入选,并且三家都已经准备好了三个阶段的投入.所以前期a出0,b出4,c出7投入到lambda项目,项目前期返回收入11

7 对于in操作,set要快于list,因为set是使用hash来存储和查找的

依次类推,直到三家的投入全部结束,所以返还的收入就是[11, 14, 17]

 

假如c有钱(c = [7,8,9,10,11]),c说:老子有钱,我要追加投入.
那ab没钱怎么办?简单!!ab就诚实的说:老子没钱 就好了(a =
[0,1,2,None,None], b = [4,5,6,None,None])

8 使用with来读写文件,保证file对象的释放

所以lambda项目就收到到这样的投入[None,None,10],
[None,None,11],这里要注意处理这些None,因为不小心他就会报NoneType

  with open(“myfile.txt”) as f:
     for line in f:
         print (line)
  f.readline() #f is cleanup here, here will get ValueError exception

a = (i for i in range(3))
b = [4, 5, 6]
c = (7, 8, 9, 10, 11)
abc = map(lambda x,y,z: str(x)+str(y)+str(z), a, b, c)
所以abc的结果为[‘047’, ‘158’, ‘269’, ‘NoneNone10’, ‘NoneNone11’]

 

map接受的也都是具有迭代的属性的参数

9 使用emumerate来遍历list

注意,当func为None的时候,map的功能就类似与zip了.说到底map也就是先集资(zip)在干事(func),func不存在的时候就剩集资(zip)了
Reduce – 二次投入

l = [1,3, 4]
for index, value in enumerate(l):
    print (‘%d, %d’ % (index, value))

标准格式reduce(func, seq[, init])

 

举个栗子:

10 分割字符串且去掉空白

a = (i for i in range(3))
result = reduce(lambda x,y: x+y, a)
result为3
reduce的工作流程为:
1.func(seq[0], seq[1]) ->seq的第一和第二元素应用到func
2.func(func(seq[0], seq[1]), seq[2])
->上一步func的结果作为func的第一个参数,seq第三个参数作为func的第二个元素
……
n.func(…func(func(seq[0], seq[1]))…,seq[n])
->上一步func的结果作为func的第一个参数,seq第n个参数作为func的第二个元素
下图可以很好的说明这个过程:

names = ‘jianpx, yy, mm, , kk’
result = [name for name in names.split(‘,’) if name.strip()]

澳门新葡萄京官网首页 1

 

                   
以上是init不存在的时候,当init存在的时候,第一步的func的第一个参数为init,seq的第一个元素为func的第二参数,后面流程就一样了
这就好比把第一阶段的盈利当作二次投资的资本在进行投资
结语
在python中函数式编程能很大程度上节约我们的开发时间,利用好了就会是自己的一大利器
文中提到的好比在可能会有不当,毕竟我不是经济专业的….海涵

11 python中的a?b:c

return_value = True if a == 1 else False  

 

12 Zen of python

>>> import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren’t special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one– and preferably only one –obvious way to do it.
Although that way may not be obvious at first unless you’re Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it’s a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea — let’s do more of those!
>>>

 

13 匿名函数lambda

add = lambda x,y : x + y
print(add(1,2))

 

14
filter(bool_func,seq),在python3以后,filter为类,filter的功能相当于过滤器。调用一个布尔函数bool_func来迭代遍历每个seq中的元素;返回一个使bool_seq返回值为true的元素的序列。
等价于(item for item in iterable if function(item))
如果function不是None;等价于(item for item in iterable if item)
如果函数是None。

a=[0,1,2,3,4,5,6,7]
b=filter(None, a)
print (list(b))
c=filter(lambda x : x %2 == 0, a)
print(list(c))
d=filter(lambda x:x>5, a)
print (list(d))
#[1, 2, 3, 4, 5, 6, 7]
#[0, 2, 4, 6]
#[6, 7]

 

15
map(func,seq1[,seq2…]):在python3以后,map为类,map将函数func作用于给定序列的每个元素,并用一个列表来提供返回值;如果func为None,func表现为身份函数,返回一个含有每个序列中元素集合的n个元组的列表。

a=[0,1,2,3,4,5,6,7]
m = map(lambda x:x+3, a)
print(list(m))
#[3, 4, 5, 6, 7, 8, 9, 10]

 

16
reduce(func,seq[,init]):在python3以后,reduce一到functools模块下,func为二元函数,将func作用于seq序列的元素,每次携带一对(先前的结果以及下一个序列的元素),连续的将现有的结果和下一个值作用在获得的随后的结果上,最后减少我们的序列为一个单一的返回值:如果初始值init给定,第一个比较会是init和第一个序列元素而不是序列的头两个元素。

import functools
a = [1,2,3,4,5]
s = functools.reduce(lambda x,y:x+y,a)
print(s)
#15

 

17 range用来返回一个list

strings = [‘a’, ‘b’, ‘c’, ‘d’, ‘e’]
for index in range(len(strings)):
    print (index)
# prints ‘0 1 2 3 4’

 

18 all用来检查list中所有的元素都满足一定的条件

numbers = [1,2,3,4,5,6,7,8,9]
if all(number < 10 for number in numbers):
    print (“Success!”)
# Output: ‘Success!’

 

19 any用来检查list中是否至少由一个元素满足一定的条件

numbers = [1,10,100,1000,10000]
if any(number < 0 for number in numbers):
    print (‘Success!’)
else:
    print(‘Fail!’)
# Output: ‘Fail!’

 

20 使用set来检查list是否有重复的元素

numbers = [1,2,3,3,4,1]
if len(numbers) == len(set(numbers)):
    print (‘List is unique!’)
# In this case, doesn’t print anything

 

21 从已有的dict构造新的dict

emails = {‘Dick’: ‘bob@example.com’, ‘Jane’: ‘jane@example.com’, ‘Stou’: ‘stou@example.net’}
email_at_dotcom = dict( [name, ‘.com’ in email] for name, email in emails.items() )
print(email_at_dotcom)
# email_at_dotcom now is {‘Dick’: True, ‘Jane’: True, ‘Stou’: False}

 

22 And+or的执行过程

对于and语句,如果and左边的是true,and右边的值将被返回作为and的结果。

对于or语句,如果or左边的是false,or将右边的值将被返回作为or的结果。

test = True
# test = False
result = test and ‘Test is True’ or ‘Test is False’
print(result)
# result is now ‘Test is True’

 

23 检查字符串是否包含子字符串 

string = ‘Hi there’ # True example
# string = ‘Good bye’ # False example
if string.find(‘Hi’) != -1:
    print (“Success!”)

string = ‘Hi there’ # True example
# string = ‘Good bye’ # False example
if ‘Hi’ in string:
    print (‘Success!’)

 

24 从list构造新的list

numbers = (1,2,3,4,5) # Since we’re going for efficiency, I’m using a tuple instead of a list 😉
squares_under_10 = (number*number for number in numbers if number*number < 10)
# squares_under_10 is now a generator object, from which each successive value can be gotten by calling .next()
for square in squares_under_10:
    print ( square)
    # prints ‘1 4 9’

 

 

参考:

 

完!