使用python的列表解析以及函数式计算来简化代码
2010-08-18 19:50
1001 查看
在我们的代码里经常会和列表,元组,字典等数据结构打交道,可以这么说,在很大程度上我们的代码就是对这些数据结构进行处理的过程,在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,列表解析等函数式的方法我们可以非常方便的对列表进行各种操作,包括对复合类型列表进行汇总计算等复杂操作,而且仅需要很少的代码
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的列表解析以及函数式计算来简化代码
- python jpype 调用Hanlp,使用列表解析.toString.encode("utf-8") 会出现乱码,需用使用for 循环
- 零基础学python-12.5 修改列表的误区以及使用for和range修改列表
- Python:爬取乌云厂商列表,使用BeautifulSoup解析
- Python 3 函数式编程之列表解析的坑
- 近期列表Recents源码流程简单解析以及ActivityManager的简单使用:
- python中使用time模块计算代码执行效率的精度测试
- 零基础学python-12.5 修改列表的误区以及使用for和range修改列表
- 使用python获取博客园作者的文章列表的超链接以及标题
- python中使用time模块计算代码执行效率的精度测试(转)
- Python使用PDFMiner解析PDF代码实例
- 纯python实现的web: tornado性能测试以及实际使用解析
- 使用python获取博客园作者的文章列表的超链接以及标题
- python中集合类型创建、更新、删除、修改以及操作符使用实例代码
- 使用Python简化循环代码
- 使用linq计算元素在列表中出现的次数c#代码
- 关于UEditor插件的使用以及UEditor数据回显问题,数据库存储标签代码前台页面如何解析问题小结
- python 列表和列表解析以及排序
- python循环的使用及range()创建数值列表和计算