楼主: z74646
1129 0

[其他] Python教程:函数式方法简化Python代码 [推广有奖]

  • 0关注
  • 1粉丝

本科生

75%

还不是VIP/贵宾

-

威望
0
论坛币
300 个
通用积分
0
学术水平
0 点
热心指数
1 点
信用等级
0 点
经验
890 点
帖子
55
精华
0
在线时间
12 小时
注册时间
2014-2-26
最后登录
2016-7-2

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币

在进行Python项目开发(http://www.maiziedu.com/course/python/)的时候,我们都会对Python代码进行简化处理,这样做不仅可以减小内存的占用量,而且后期的维护修改也简单清晰。知道了简化代码的好处后,我们现在是不是该想想如何对Python代码进行简化呢?

在Python代码中经常会和列表、元组、字典等数据结构打交道,因此处理代码的时候会相对比较方便。下面就讲讲Python借鉴了Lisp中很多函数式计算的方法来处理列表,可以极大的简化我们的代码。

set() 将元组,列表转化成没有重复项的集合

list()将集合,元组转化成列表

tuple()将集合,列表转化成元组

列表解析:[返回值 for 元素 in 列表 if 条件] 比如 [num for num in xrange(100) if num%2==0] 返回0~99之间的偶数列表

map(func,list):将list的每一个元素传递给func的函数,这个函数有一个参数,且返回一个值,map将每一次调用函数返回的值组成一个新列表返回

filter(func,list):将list的每一个元素传递给func的函数,这个函数有一个参数,返回bool类型的值,filter将返回True的元素组成新列表返回

reduce(func,list):将list的元素,挨个取出来和下一个元素通过func计算后将结果和再下一个元素继续计算,比如

ls=[1,3,5,7]

reduce(lambda x,y:x+y,ls)

的计算过程就是 1+3=4 然后4+5得到结果9,再加7,以此类推,最后返回最终计算的结果

下面我们用实际的例子来看如何运用这几个函数

1.列表去重

如果有一个列表ls=[1,3,2,5,2,1,3,4,6]需要去掉其中重复的项,怎么做?

最简单的办法   ls=list(set(ls))

2.假如有列表:

books=[

        {"name":"C#从入门到精通","price":23.7,"store":"卓越"},

        {"name":"ASP.NET高级编程","price":44.5,"store":"卓越"},

        {"name":"C#从入门到精通","price":24.7,"store":"当当"},

        {"name":"ASP.NET高级编程","price":45.7,"store":"当当"},

        {"name":"C#从入门到精通","price":26.7,"store":"新华书店"},

        {"name":"ASP.NET高级编程","price":55.7,"store":"新华书店"},

2.1 求《ASP.NET高级编程》价格最便宜的店:

storename=min([b for b in books if b['name']=="ASP.NET高级编程"],key=lambda b:b.price)["store"]

过程:先用列表解析取出《ASP.NET高级编程》的列表,通过min函数,比较字典的price键获取price最小的项

2.2 求在新华书店购买两本书一样一本要花的钱:

price=sum([b['price'] for b in books if b['store']=="新华书店"])

2.3 求列表中有那几本书:

booknames=list(set([b['name'] for b in books]))

2.4 列表里当当的书都打5折:

books=map(lambda b:dict(name=b['name'],price=b['price']*0.5,store=b['store']),books)

2.5 《C#从入门到精通》的平均价格:

avg=(lambda ls:sum(ls)/len(ls))([b.price for b in books if b['name']=="C#从入门到精通"])

2.6 求每本书的平均价格:

book_avg=map(lambda bookname:dict(name=bookname,avg=(lambda ls:sum(ls)/len(ls))([b.price for b in books if b['name']==bookname])),list(set([b['name'] for b in books])))

这段代码放在一行比较难看懂,但是格式化一下就很好懂了,构建的过程如下:

step1 要求每本书的平均价格,首先要得到共有几本书,方法见2.3,得到去重的书名列表

list(set([b['name'] for b in books])) #去重后的书名列表

step2 要求每一本书的均价,需要将计算均价的函数映射到每一本书上,于是

map(

    #计算均价的函数,

    list(set([b['name'] for b in books])) #去重后的书名列表

)

step3 加入计算单本书均价的函数,参考2.5的方法,由于只用一行,所以用lambda来搞定:

func=lambda bookname:(lambda ls:sum(ls)/len(ls))([b.price for b in books if b['name']==bookname])

step4 将计算单本均价的lambda函数加入map中,得到最终结果:

经过格式化后的结果,前面的单行代码可以格式化为下面容易阅读的形式

map(

    lambda bookname:reduce(

                        lambda bookname:

        dict(

          name=bookname,

          avg=(lambda ls:sum(ls)/len(ls))([b.price for b in books if b['name']==bookname])

        ),

    list(

         set(

             [b['name'] for b in books]

         )

    ) #去重后的书名列表

)

从上面的例子我们可以看到,利用map,reduce,filter,列表解析等函数式的方法我们可以很方便的对列表进行各种操作,包括对复合类型列表进行汇总计算等复杂操作,而且需要敲打的代码也很少,这样也能提高我们的开发速度,是不是觉得很便利呢,若你有时间,可以自己尝试下,与自己以前采用的方法对比下,看看那个比较实用。


二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:Python教程 python Lambda reduce filter 项目开发 而且 如何

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注cda
拉您进交流群

京ICP备16021002-2号 京B2-20170662号 京公网安备 11010802022788号 论坛法律顾问:王进律师 知识产权保护声明   免责及隐私声明

GMT+8, 2024-4-27 14:43