[英]python map function (+ lambda) involving conditionals (if)
我很好奇是否有可能用map()
函數做一些我可以通過列表理解來做的事情。
例如,拿這個列表組合:
example_list = [x*2 for x in range(5) if x*2/6. != 1]
顯然,這給了我 [0, 2, 4, 8]。
如何使用map()
函數進行等效? 這樣做會給我一個語法錯誤。
example_map = map(lambda x:x*2 if x*2/6. != 1, range(5))
只是想更好地了解如何使用此功能。
您必須將map
環繞在列表周圍的filter
中:
example_map = map(lambda x: x*2, filter(lambda x: x*2/6. != 1, range(5)))
或者,您可以filter
您的map
而不是map
您的filter
。
example_map = filter(lambda x: x/6. != 1, map(lambda x: x*2, range(5)))
請記住,您現在正在過濾結果而不是原始結果(即lambda x: x/6. != 1
而不是lambda x: x*2/6. != 1
因為x
已經從地圖中翻倍了)
哎呀,如果你真的想,你可以種把它與一個條件表達式都在一起
example_map = map(lambda x: x*2 if x*2/6. != 1 else None, range(5))
但它會給你留下[0, 2, 4, None, 8]
。 filter(None, example_map)
將刪除None
s並按預期離開您[0, 2, 4, 8]
。
除了建議一些解決方案的其他答案之外,您的語法錯誤的原因是map
函數:
將函數應用於可迭代的每個項目並返回結果列表。
所以結果與你的迭代長度相同。如果你使用if
語句,你也需要指定一個else
。
>>> map(lambda x:x*2 if x*2/6. != 1 else None, range(5))
[0, 2, 4, None, 8]
作為替代方法,您可以使用itertools.ifilter
來過濾您的 iterable :
>>> from itertools import ifilter
>>> map(lambda x:x*2,ifilter(lambda x: x*2/6. != 1,range(5)))
[0, 2, 4, 8]
請注意,由於您不需要過濾列表的結果,而您只想將其傳遞給map
因此使用ifilter
效率更高,因為它返回一個生成器,並且您可以為長列表節省大量內存;)(所有這些都在 python 2 中)並在python 3 filter
返回生成器)
您可以分兩個階段進行,第一階段通過在列表上應用過濾器,第二階段通過在輸出列表上應用映射函數
list(map(lambda x:x*2, filter(lambda x: x*2/6 != 1 , [x for x in range(5)])))
[0, 2, 4, 8]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.