filter、map、reduce、lambda、yield的用法

python 的几个小函数

filter、map、reduce、lambda、yield

有了它们,最大的好处是程序更简洁;没有它们,程序也可以用别的方式实现,只不过麻烦一些罢了。所以,还是能用则用之吧。

lambda

lambda函数,是一个只用一行就能解决问题的函数,听着是多么诱人呀。看下面的例子:
>>> def add(x):     #定义一个函数,将输入的变量增加3,然后返回增加之后的值

...     x +=3

...     return x

...

>>> numbers = range(10)

>>> numbers

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]  #有这样一个list,想让每个数字增加3,然后输出到一个新的list中 
 >>> new_numbers = []

>>> for i in numbers:

...     new_numbers.append(add(i))  #调用add()函数,并append到list中

...

>>> new_numbers

[3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

 在这个例子中,add()只是一个中间操作。当然,上面的例子完全可以用别的方式实现。比如:
>>> new_numbers = [ i+3 for i in numbers ]

>>> new_numbers

[3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

 首先说明,这种列表解析的方式是非常非常好的。

但是,我们偏偏要用lambda这个函数替代add(x),如果看官和我一样这么偏执,就可以:
>>> lam = lambda x:x+3

>>> n2 = []

>>> for i in numbers:

...     n2.append(lam(i))

...

>>> n2

[3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

这里的lam就相当于add(x),请看官对应一下,这一行lambda x:x+3就完成add(x)的三行(还是两行?),特别是最后返回值。还可以写这样的例子:
>>> g = lambda x,y:x+y  #x+y,并返回结果

>>> g(3,4)

7

>>> (lambda x:x**2)(4)  #返回4的平方

16
 通过上面例子,总结一下lambda函数的使用方法:
 •在lambda后面直接跟变量
 •变量后面是冒号
 •冒号后面是表达式,表达式计算结果就是本函数的返回值
 
为了简明扼要,用一个式子表示是必要的:
lambda arg1, arg2, ...argN : expression using arguments

 要特别提醒看官:虽然lambda 函数可以接收任意多个参数 (包括可选参数) 并且返回单个表达式的值,但是lambda 函数不能包含命令,包含的表达式不能超过一个。不要试图向 lambda 函数中塞入太多的东西;如果你需要更复杂的东西,应该定义一个普通函数,然后想让它多长就多长。

就lambda而言,它并没有给程序带来性能上的提升,它带来的是代码的简洁。比如,要打印一个list,里面依次是某个数字的1次方,二次方,三次方,四次方。用lambda可以这样做:
>>> lamb = [ lambda x:x,lambda x:x**2,lambda x:x**3,lambda x:x**4 ]

>>> for i in lamb:

...     print i(3),

...

3 9 27 81

 lambda做为一个单行的函数,在编程实践中,可以选择使用。根据我的经验,尽量少用,因为它或许更多地是为减少单行函数的定义而存在的。

map

先看一个例子,还是上面讲述lambda的时候第一个例子,用map也能够实现:
>>> numbers

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]      #把列表中每一项都加3 
 >>> map(add,numbers)                #add(x)是上面讲述的那个函数,但是这里只引用函数名称即可

[3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
 >>> map(lambda x: x+3,numbers)      #用lambda当然可以啦

[3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

map()是python的一个内置函数,它的基本样式是:map(func, seq),func是一个函数,seq是一个序列对象。在执行的时候,序列对象中的每个元素,按照从左到右的顺序,依次被取出来,并塞入到func那个函数里面,并将func的返回值依次存到一个list中。

在应用中,map的所能实现的,也可以用别的方式实现。比如:
>>> items = [1,2,3,4,5]

>>> squared = []

>>> for i in items:

...     squared.append(i**2)

...

>>> squared

[1, 4, 9, 16, 25] 
 >>> def sqr(x): return x**2

...

>>> map(sqr,items)

[1, 4, 9, 16, 25]
 >>> map(lambda x: x**2,items)

[1, 4, 9, 16, 25]
 >>> [ x**2 for x in items ]     #这个我最喜欢了,一般情况下速度足够快,而且可读性强

[1, 4, 9, 16, 25]

条条大路通罗马,以上方法,在编程中,自己根据需要来选用啦。

在以上感性认识的基础上,在来浏览有关map()的官方说明,能够更明白一些。
map(function, iterable, ...) 
 Apply function to every item of iterable and return a list of the results. If additional iterable arguments are passed, function must take that many arguments and is applied to the items from all iterables in parallel. If one iterable is shorter than another it is assumed to be extended with None items. If function is None, the identity function is assumed; if there are multiple arguments, map() returns a list consisting of tuples containing the corresponding items from all iterables (a kind of transpose operation). The iterable arguments may be a sequence or any iterable object; the result is always a list.

 理解要点:
 •对iterable中的每个元素,依次应用function的方法(函数)(这本质上就是一个for循环)。
 •将所有结果返回一个list。
 •如果参数很多,则对么个参数并行执行function。

例如
>>> lst1 = [1,2,3,4,5]

>>> lst2 = [6,7,8,9,0]

>>> map(lambda x,y: x+y, lst1,lst2)     #将两个列表中的对应项加起来,并返回一个结果列表

[7, 9, 11, 13, 5]
请看官注意了,上面这个例子如果用for循环来写,还不是很难,如果扩展一下,下面的例子用for来改写,就要小心了:代码如下:
>>> lst1 = [1,2,3,4,5]

>>> lst2 = [6,7,8,9,0]

>>> lst3 = [7,8,9,2,1]

>>> map(lambda x,y,z: x+y+z, lst1,lst2,lst3)

[14, 17, 20, 15, 6]这才显示出map的简洁优雅。

reduce忍不住还得来点废话。不知道看官是不是听说过MapReduc,如果没有,那么Hadoop呢?如果还没有,就google一下。下面是我从维基百科上抄下来的,共赏之。
MapReduce是Google提出的一个软件架构,用于大规模数据集(大于1TB)的并行运算。概念“Map(映射)”和“Reduce(化简)”,及他们的主要思想,都是从函数式编程语言借来的,还有从矢量编程语言借来的特性。

不用管是不是看懂,总之又可以用开头的思想意淫一下了,原来今天要鼓捣的这个reduce还跟大数据有关呀。不管怎么样,你有梦一般的感觉就行。

reduce

回到现实,清醒一下,继续敲代码:
>>> reduce(lambda x,y: x+y,[1,2,3,4,5])
15


还记得map是怎么运算的吗?忘了?看代码:
>>> list1 = [1,2,3,4,5,6,7,8,9]

>>> list2 = [9,8,7,6,5,4,3,2,1]

>>> map(lambda x,y: x+y, list1,list2)

[10, 10, 10, 10, 10, 10, 10, 10, 10]

 看官对比一下,就知道两个的区别了。原来map是上下运算,reduce是横着逐个元素进行运算。

权威的解释来自官网:reduce(function, iterable[, initializer])
Apply function of two arguments cumulatively to the items of iterable, from left to right, so as to reduce the iterable to a single value. For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates ((((1+2)+3)+4)+5). The left argument, x, is the accumulated value and the right argument, y, is the update value from the iterable. If the optional initializer is present, it is placed before the items of the iterable in the calculation, and serves as a default when the iterable is empty. If initializer is not given and iterable contains only one item, the first item is returned. Roughly equivalent to:
代码:
 def reduce(function, iterable, initializer=None):

    it = iter(iterable)

    if initializer is None:

        try:

            initializer = next(it)

        except StopIteration:   

            raise TypeError('reduce() of empty sequence with no initial value')   

    accum_value = initializer                                                                  

    for x in it:

        accum_value = function(accum_value, x)   

    return accum_value

如果用我们熟悉的for循环来做上面reduce的事情,可以这样来做:

代码:

>>> lst = range(1,6)

>>> lst

[1, 2, 3, 4, 5]

>>> r = 0

>>> for i in range(len(lst)):

...     r += lst[i]

...

>>> r

15

for普世的,reduce是简洁的。

为了锻炼思维,看这么一个问题,有两个list,a = [3,9,8,5,2],b=[1,4,9,2,6],计算:a[0]b[0]+a1b1+...的结果。

代码如下:

>>> a

[3, 9, 8, 5, 2]

>>> b

[1, 4, 9, 2, 6] 
 >>> zip(a,b)        #复习一下zip,下面的方法中要用到

[(3, 1), (9, 4), (8, 9), (5, 2), (2, 6)]
 >>> sum(x*y for x,y in zip(a,b))    #解析后直接求和

133
 >>> new_list = [x*y for x,y in zip(a,b)]    #可以看做是上面方法的分布实施

>>> #这样解析也可以:new_tuple = (x*y for x,y in zip(a,b))

>>> new_list

[3, 36, 72, 10, 12]

>>> sum(new_list)     #或者:sum(new_tuple)

133
 >>> reduce(lambda sum,(x,y): sum+x*y,zip(a,b),0)    #这个方法是在耍酷呢吗?

133
 >>> from operator import add,mul            #耍酷的方法也不止一个

>>> reduce(add,map(mul,a,b))

133
 >>> reduce(lambda x,y: x+y, map(lambda x,y: x*y, a,b))  #map,reduce,lambda都齐全了,更酷吗?

133

filter

filter的中文含义是“过滤器”,在python中,它就是起到了过滤器的作用。首先看官方说明:
filter(function, iterable) 
 Construct a list from those elements of iterable for which function returns true. iterable may be either a sequence, a container which supports iteration, or an iterator. If iterable is a string or a tuple, the result also has that type; otherwise it is always a list. If function is None, the identity function is assumed, that is, all elements of iterable that are false are removed.
 Note that filter(function, iterable) is equivalent to [item for item in iterable if function(item)] if function is not None and [item for item in iterable if item] if function is None.

这次真的不翻译了(好像以往也没有怎么翻译呀),而且也不解释要点了。请列位务必自己阅读上面的文字,并且理解其含义。英语,无论怎么强调都是不过分的,哪怕是做乞丐,说两句英语,没准还可以讨到英镑美元呢。

通过下面代码体会:
>>> numbers = range(-5,5)

>>> numbers

[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4] 
 >>> filter(lambda x: x>0, numbers)

[1, 2, 3, 4]
 >>> [x for x in numbers if x>0]     #与上面那句等效

[1, 2, 3, 4]
 >>> filter(lambda c: c!='i', 'qiwsir')  #能不能对应上面文档说明那句话呢?

'qwsr'                                  #“If iterable is a string or a tuple, the result also has that type;”

 至此,用两此介绍了几个小函数,这些函数在对程序的性能提高上,并没有显著或者稳定预期,但是,在代码的简洁上,是有目共睹的。有时候是可以用来秀一秀,彰显python的优雅和自己耍酷。

转:http://www.jb51.net/article/56024.htm

 *************************************************************************************************************************

 自己应用的例子,实现插入数据库多条记录

if __name__=="__main__":
    threadname =['baidu200','baidu200','baidu200','baidu200','baidu200','baidu200']
    timeinterval = ['200','201','202','203','204','205']
    responseduration = ['300','301','302','303','304','305']
    averageduration = ['400','401','402','403','404','405']
    hitspersecond = ['500','501','502','503','504','505']
    tps =  ['600','601','602','603','604','605']
    do_number =[3,3,3,3,3,3]
    print "datas:",datas
    print "11111"
    conn=MySQLdb.connect(host='10.154.156.224',user='root',passwd='scpsql',db='scp',port=3306)
    cursor = conn.cursor()
    print "2222"
    sql = "insert into service_chartdata (jmetertask_id,test_name,threadname,timeinterval,responseduration,averageduration,hitspersecond,tps,do_number) values (%s,%s,%s,%s,%s,%s,%s,%s,%s)"
    try:
        print "3333"
        cursor.executemany(sql,datas)
    except Exception as e:
        print "mysql insert error"
    finally:
        cursor.close()
        conn.commit()
        conn.close()

**************************************************************************************************************************

   map 和lambda 应用

>>> list1 = [1,'ww',2]
>>> list2 = [2,'rr',8]
>>> map(lambda x,y : (x,y),list1,list2)
[(1, 2), ('ww', 'rr'), (2, 8)]

 

TypeError: reduce() of empty sequence with no initial value TypeError: reduce() of empty sequence with no initial value 一般出现在列表元素被移除,或者是一个空数组的情况下,意思就是得加一个空值,给一个初始值0或1做为初始值.一般就0吧,代码里面有300个维度,所以也给了300维度的0.就不报错了。 但是下面的词向量余弦测试比较会报错,原因是list不能使用reshape,需要将其转化为array,然后就可以使用reshape了,所以用np.array([0] * 300)转化 ... 阅读详情

相关推荐

使用reduce报TypeError: Reduce of empty array with no initial value处理方法

报错截图: 大致为: ERROR Error: Uncaught (in promise): TypeError: Reduce of empty array with no initial value TypeError: Reduce of empty array with no initial value at Array.reduce (<anonymous>) 报错原因: Reduce函数有选择性的接收 initialValue (将会被用作回调函数第一次被调用的参数)。然

weixin_45680024的博客 4780

Python reduce函数

搜了很多介绍,很多解释者也给了很多例子,但是总感觉模模糊糊的,直到看到官方的原函数,豁然开朗。 官方解释: 将一个可迭代的对象应用到一个带有两个参数的方法上,我们称之为appFun,遍历这个可迭代对象,将其中的元素依次作为appFun的参数,但这个函数有两个参数,作为哪个参数呢?有这样的规则,看一下下面reduce方法的实现,有三个参数,第一个参数就是上面说的appFun,第二个参数就是...

harhy的专栏 526

python新手笔记之python高级函数编程

python是一种非常强强大的脚本语言,不仅在于编程简洁,而且借鉴了很多其他语言的精妙之处,开始学python的时候听说python是对于编程初学者而言最好的语言,我现在觉得这句话一点也不意外,python确实做到了精简与强大并存,话不多说,整理一下python的超级强大的高级函数   1,reduce——递归编程的利器  问题入门:我们现在需要计算一下N的阶乘,能够想到的方法自然是递归...

luchi007的专栏 446

pythonlambdayieldmapfilterreduce的使用

python中允许使用lambda关键字定义一个匿名函数。所谓的匿名函数就是说使用一次或者几次之后就不再需要的函数,属于“一次性”函数。yield关键字可以把一个函数变成一个生成器(generator)。筛选函数用于对序列中的元素进行筛选,最终获取符合条件的序列。yield可以将函数执行的中间结果返回但是不结束程序。对序列中的所有函数进行类操作。map函数用于遍历序列。实现一个range函数。

Python编程学习的博客 698

Python特殊语法:filtermapreducelambdayield

Python内置了一些非常有趣但非常有用的函数,充分体现了Python的语言魅力! filter(function, sequence):对sequence中的item依次执行function(item),将执行结果为True的item组成一个List/String/Tuple(取决于sequence的类型)返回: >>> def f(x): return x % 2 != 0 and x %

朝着梦想 渐行前进 5561

关于python当中lambdayieldmapreducefilter、sorted的总结

1、yield的使用,参考:https://stackoverflow.com/questions/231767/the-python-yield-keyword-explained/231855#231855    来自于stackoverflow的,解答者经验非常的丰富,把yield的功能由简单到复杂都介绍了一遍。总结几个要点。    1、generator:只被遍历一次之后便从内存当中删

a123456ei的专栏 3331

三元运算式、lambda表达式、内置函数mapreducefilter以及yield生成器

一、三元运算(式) 对于一般简单的if else条件判断句可以用三元运算来表示 具体模式为: 1 2 3 4 5 6 ifcondition: expr1 else: expr2 等价于: expr1ifconditionelseexpr2 解释:如果if condition条件成立就执行e...

weixin_33849942的博客 110

Python函数之lambda,内置函数,yield生成器等

lambda 1,用于处理简单逻辑 2,自动返回数据(return) 单参数 >>> func2 = lambda a: a+1>>> result = func2(1000)>>> print result1001 多参数 >>> func3 = lambda a,b: a+b>>&g...

abtmh02622的专栏 144

python 函数 maplambda

开篇就要提到一个大的话题:编程范型。什么是编程范型?引用维基百科中的解释: 编程范型或编程范式(英语:Programming paradigm),(范即模范之意,范式即模式、方法),是一类典型的编程风格,是指从事软件工程的一类典型的风格(可以对照方法学)。如:函数式编程、程序编程、面向对象编程、指令式编程等等为不同的编程范型。 编程范型提供了(同时决定了)程序员对程序执行的看法。例如,在面向...

hiekay的博客 492

Python 10 个习惯用法,第二期

Python 使用习惯第一期:Python 10 个习惯用法,看看你都知道不?今天是 Python 使用习惯第二期:11-2011 字典默认值In[1]:d={'a&#39...

算法channel 358

lambda小应用(Python)

python内置支持不少函数式编程思想比如内置函数reduce,map,filter,any,all支持lazy求值(yield)的用法支持lambda我们看几个简单的例子体验一下lambda的厉害题一:求最大公约数gcd = lambda x,y: gcd(y,x%y) if x%y else y print gcd(a,b)题二:求100以内的素数,并以空格分开后将结果输出print ' '....

cylon的专栏 935

优雅的python_优雅的python

在知乎上看到的问题——python有哪些优雅的代码实现。下面的代码大概也算不上优雅。一下代码在python3中实现更多内容可见:http://book.pythontips.com/en/latest/args_and_kwargs.htmllambda函数的使用lambda,又称匿名函数。当我们在传入函数时,有些时候,不需要显式地定义函数,直接传入匿名函数更方便。比如命名一个普通的函数:def ...

weixin_39630410的博客 108

柏老师python笔记(四)

# encoding: utf-8 """ author: Leo date: 2017-6-21 """ # 函数的使用 # 参数的收集(Python)使用这种方法解决参数个数不确定性 # *arg返回的是一个元祖的类型,如果不给*arg传值的话那么他就是一个空的元祖 def func(x, *arg):     print x     result = x    

jinjiao_的博客 291

4天学会python_Python第四天

冒泡算法:循环with.open("ha.cfg") as obji:for line in boj #逐行读取,效率更高startswith空字符串的bool值为falsejson1、内部必须为双引号。2、字符转成列表哦简化的函数定义lambda1、自动return2、处理简单逻辑func = lambda arg: arg +1等同于def func(arg):return arg+1列表每项...

weixin_39628271的博客 44

Python核心编程笔记 - 第11章 函数式编程

Python核心编程笔记 - 第11章 函数式编程

FinixLei的专栏 (https://github.com/FinixLei) 906

python 常见函数_python常用函数

1. range与xrangerange([start,] stop[, step])range可以创建一个从start到stop(不包含)的列表,用在循环中时,会一次性把列表都加载到内存中。xrange([start,] stop[, step])xrange可以创建一个从start到stop(不包含)的生成器,用在循环中时,不会一次性加载所有内容,而是每次调用返回其中的一个值,因此始终占用很小...

weixin_39604557的博客 123
上一篇: vi使用技巧
下一篇: liunx文件操作技巧
km_moon
博客等级 码龄14年 10粉丝 244原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值