设为首页 收藏本站
查看: 881|回复: 0

[经验分享] 使用python的列表解析以及函数式计算来简化代码

[复制链接]

尚未签到

发表于 2015-4-21 08:16:28 | 显示全部楼层 |阅读模式
在我们的代码里经常会和列表,元组,字典等数据结构打交道,可以这么说,在很大程度上我们的代码就是对这些数据结构进行处理的过程,在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,列表解析等函数式的方法我们可以非常方便的对列表进行各种操作,包括对复合类型列表进行汇总计算等复杂操作,而且仅需要很少的代码

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-59012-1-1.html 上篇帖子: [Python]Socket的TCP/UDP应用 下篇帖子: Python 3 os.walk使用详解
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表