iT邦幫忙

2025 iThome 鐵人賽

DAY 21
0
Software Development

從零開始學 Python系列 第 21

Day 21 – 內建函式 map / filter / reduce 與匿名函式 lambda

  • 分享至 

  • xImage
  •  

今天的學習重點

  • 函數式工具的概念
  • map():批次轉換
  • filter():條件篩選
  • reduce():累積運算
  • lambda:匿名函式(一次性小函式)

一、函數式工具的概念

在程式設計中有兩大主要風格:

  1. 命令式(Imperative)
  • 一步步告訴電腦「怎麼做」。
  • 例如用 for 迴圈,不斷 append() 把結果加進清單。
nums = [1, 2, 3, 4, 5]
squares = []
for n in nums:
    squares.append(n ** 2)
print(squares)
# [1, 4, 9, 16, 25]
  1. 函數式(Functional)
  • 強調「做什麼(what)」而不是「怎麼做(how)」。
  • 把運算邏輯封裝成「函數」,再把資料交給這些函數處理。
  • 常見的工具:map(轉換)、filter(篩選)、reduce(累積)。
    例如用 map,只要一行就能完成平方運算:
nums = [1, 2, 3, 4, 5]
squares = list(map(lambda n: n ** 2, nums))
print(squares)
# [1, 4, 9, 16, 25]

這樣的寫法像是在「描述規則」而不是「自己控制流程」。好處是簡潔、可讀性高,而且能更容易搭配其他函數組合。

二、map() – 批次轉換

語法:

map(function, iterable)
  • function:你要套用的函式(可以是已定義的函式,或是 lambda 匿名函式)。
  • iterable:一個可迭代物件(例如 list、tuple、字串等)。
  • map 會把 function 套用到 iterable 裡的每個元素,然後回傳一個「map 物件」。
    所以我們通常會再用 list() 把它轉成串列,方便查看。

將一個函式套用到序列中的每個元素。

nums = [1, 2, 3, 4, 5]
squares = list(map(lambda x: x ** 2, nums))
print(squares)

輸出:

[1, 4, 9, 16, 25]

三、filter() – 條件篩選

語法:

filter(function, iterable)
  • function:判斷用的「條件函式」(又叫 predicate)。對每個元素回傳 True/False。
  • iterable:可迭代物件(list/tuple/字串/生成器…)。
  • 回傳:一個惰性迭代器(要用 list() 包起來才會看到結果,或用 for 迴圈取用)。
    重點:只保留回傳 True 的那些元素;順序不變、原始資料不會被修改。
nums = [1, 2, 3, 4, 5, 6, 7, 8]
even = list(filter(lambda x: x % 2 == 0, nums))
print(even)

輸出:

[2, 4, 6, 8]

四、reduce() – 累積運算

語法:

reduce(function, iterable)

來自 functools 模組,用於把序列中的值依序「合併」起來。

from functools import reduce

nums = [1, 2, 3, 4, 5]
product = reduce(lambda x, y: x * y, nums)
print(product)   # 1*2*3*4*5=120

reduce 在 Python 裡比較少用,因為很多情況用 for 或 sum() 就能達成,但在需要「把所有元素合併成一個值」的時候很方便。

五、lambda – 匿名函式

  • 匿名函式:不取名字(或取個臨時變數名),只用一個「運算式」 定義行為。
  • 語法:lambda 參數們: 表達式
  • 回傳值:表達式的結果(不用也不能寫 return)。
  • 適合一次性、很短、丟到別的函式當參數的小功能。

lambda 可以建立臨時的小函式,不需要用 def:

add = lambda a, b: a + b
print(add(3, 5))   # 8

等同於:

def add(a, b):
    return a + b

語法速記

lambda x: x + 1                 # 一個參數
lambda x, y=0: x + y            # 預設參數
lambda *args: sum(args)         # 可變參數
lambda x, **kw: kw.get('k', x)  # 關鍵字參數

限制: 只能寫「運算式」,不能有多行、return/for/while/print(print 可當函式呼叫,但不建議在 lambda 放副作用)、try…等「敘述」。

配合 map / filter / reduce

nums = [1, 2, 3, 4, 5]

# map:批次轉換
squares = list(map(lambda x: x**2, nums))               # [1, 4, 9, 16, 25]

# filter:條件篩選
evens = list(filter(lambda x: x % 2 == 0, nums))        # [2, 4]

# reduce:累積運算
from functools import reduce
product = reduce(lambda a, b: a * b, nums)              # 120

六、綜合練習

找出 1~30 中能被 3 整除的平方數

nums = range(1, 31)
result = list(
    map(lambda x: x ** 2,
        filter(lambda x: x % 3 == 0, nums))
)
print(result)

輸出:

[9, 36, 81, 144, 225, 324, 441, 576, 729]
  • filter → 先挑出符合條件的數字(這裡是 3 的倍數)。
  • map → 再把這些數字變成平方。

七、學習心得

今天學到 map、filter、reduce 搭配 lambda,感覺就像是「把迴圈濃縮成一個公式」。用一行就能表達「轉換」、「篩選」、「累積」的邏輯。不過如果邏輯太複雜,塞在一行反而會讓程式難以閱讀,所以要拿捏使用時機。
明天要進入物件導向 OOP 的基礎,學習 class 與 object。這是 Python 與 Java 都有的核心觀念,只是 Python 的語法更簡潔。透過 OOP 可以把資料與功能包裝成「物件」,更貼近真實世界的思維,也能讓程式結構更清晰、更容易擴充。


上一篇
Day 20 – 列表生成式(List Comprehension)
下一篇
Day 22 – 物件導向 OOP 基礎:Class 與 Object
系列文
從零開始學 Python30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言