在我們的代碼裡經常會和列表,元組,字典等資料結構打交道,可以這麼說,在很大程度上我們的代碼就是對這些資料結構進行處理的過程,在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,列表解析等函數式的方法我們可以非常方便的對列表進行各種操作,包括對複合類型列表進行匯總計算等複雜操作,而且僅需要很少的代碼