APCS 必學 Python 程式設計:列表推導式

TL;DR 重點摘要
- 列表推導式(List Comprehension)是 Python 最具代表性的寫法之一,能把 for 迴圈濃縮成一行
- 比起傳統 for 迴圈寫法,列表推導式更簡潔、執行速度也更快
- 加上 if 條件後,可以一行完成「篩選 + 轉換」的雙重任務
- APCS 解題時用列表推導式可以省下大量行數,讓主邏輯更清楚
- 這是從「Python 初學者」進階到「Python 使用者」的關鍵分水嶺
目錄
什麼是列表推導式
列表推導式的概念用一句話講就是:用一行寫出一個建構新列表的迴圈。
它的基本格式長這樣:
[ 表達式 for 變數 in 來源 ]
舉個例子,要建立 1 到 5 的平方列表:
squares = [x * x for x in range(1, 6)]
print(squares)
# 輸出: [1, 4, 9, 16, 25]
讀法:「對於每個從 range(1, 6) 出來的 x,把 x * x 收集成新列表」。
從 for 迴圈到列表推導式
我們來比較同樣的功能用兩種寫法的差別。任務:把 [1, 2, 3, 4, 5] 每個元素都乘以 10。
用 for 迴圈寫:
nums = [1, 2, 3, 4, 5]
result = []
for x in nums:
result.append(x * 10)
print(result)
# 輸出: [10, 20, 30, 40, 50]
四行程式碼,要先建空列表、寫迴圈、再 append()。
用列表推導式寫:
nums = [1, 2, 3, 4, 5]
result = [x * 10 for x in nums]
print(result)
# 輸出: [10, 20, 30, 40, 50]
一行做完。而且當你習慣這個寫法之後,讀起來會比 for 迴圈更直覺——因為它的順序就是「我想要什麼 ← 從哪裡來」。
加上 if 條件:一行做兩件事
列表推導式真正強大的地方,是可以一邊轉換、一邊篩選。格式是:
[ 表達式 for 變數 in 來源 if 條件 ]
例如,要從 1 到 20 中挑出所有偶數:
evens = [x for x in range(1, 21) if x % 2 == 0]
print(evens)
# 輸出: [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
或者,要把一串成績裡及格的科目「加 5 分」:
scores = [55, 72, 48, 90, 63, 38]
boosted = [s + 5 for s in scores if s >= 60]
print(boosted)
# 輸出: [77, 95, 68]
這行程式碼同時做了篩選(只取大於等於 60 的)和轉換(每個都加 5)。用 for 迴圈寫至少要 4-5 行。
APCS 實戰:三個常見應用
應用一:讀進整行數字並只取偶數
# 輸入: 3 8 5 12 7 4 9
nums = list(map(int, input().split()))
evens = [x for x in nums if x % 2 == 0]
print(evens)
# 輸出: [8, 12, 4]
應用二:批次計算每筆資料的平方
# 輸入: 1 2 3 4 5
nums = list(map(int, input().split()))
squares = [x * x for x in nums]
print(squares)
# 輸出: [1, 4, 9, 16, 25]
應用三:從字串中取出所有數字字元
text = "abc123def45g"
digits = [c for c in text if c.isdigit()]
print(digits)
# 輸出: ['1', '2', '3', '4', '5']
isdigit() 是字串方法,會檢查這個字元是不是數字。這在處理「混合文字和數字」的測資時非常實用。
列表推導式 vs map():什麼時候用哪個?
第二篇我們學了 map(),它跟列表推導式很像,但各有適合的場合:
# 簡單套用一個函式 → map() 比較簡潔
nums = list(map(int, input().split()))
# 需要表達式或條件 → 列表推導式比較直覺
squares = [x * x for x in nums]
evens = [x for x in nums if x % 2 == 0]
判斷原則:
- 只是「轉換型態」或「套用單一函式」→ 用
map() - 需要「做運算」或「加條件」→ 用列表推導式
實際上很多 APCS 高手兩種都用,看哪個寫法在當下最清楚就用哪個。
使用時容易出錯的地方
問題一:條件位置寫錯
if 條件在後面是「篩選」,如果想做「條件式轉換」要用 if-else 並放在前面:
# 篩選:只保留偶數
[x for x in range(10) if x % 2 == 0]
# 結果: [0, 2, 4, 6, 8]
# 轉換:偶數保留,奇數變 -1
[x if x % 2 == 0 else -1 for x in range(10)]
# 結果: [0, -1, 2, -1, 4, -1, 6, -1, 8, -1]
兩種 if 的位置和語意完全不同,要分清楚。
問題二:寫得太複雜反而難讀
列表推導式的優點是簡潔,但如果塞太多邏輯進去,反而會比 for 迴圈難讀:
# 太複雜,不建議這樣寫
result = [x * 2 if x > 0 else -x for x in nums if x != 0 and x % 3 == 0]
判斷原則:如果一行寫不下要折行才看得懂,就改回 for 迴圈。程式碼是寫給人讀的,不是越短越好。
問題三:忘了用 [] 包起來
# 錯誤:這是「生成器表達式」,不是列表
result = (x * 2 for x in nums)
# 正確:列表推導式要用方括號
result = [x * 2 for x in nums]
圓括號 () 會產生「生成器(generator)」,雖然 Python 也接受,但跟列表用法不同,初學階段先用 [] 就好。
列表推導式是 Python 寫法現代化的代表。當你開始自然地寫出 [x * 2 for x in nums] 這類程式碼,你已經跟「死記語法」的階段告別,進入「用 Python 風格思考」的世界了。
下一篇開始我們會進入 APCS 解題的核心 —— 二維列表與棋盤地圖,讓你學會處理矩陣、迷宮、棋盤這類常見的考題類型。
AI導師 Python 程式教學 - 隨時可以學習

?常見問題 FAQ
Q.列表推導式跟 for 迴圈的差別在哪?
兩者結果一樣,但列表推導式可以把多行 for 迴圈壓縮成一行,而且執行速度通常更快。比較看看「把列表每個元素乘以 10」:
# for 迴圈:4 行
result = []
for x in nums:
result.append(x * 10)
# 列表推導式:1 行
result = [x * 10 for x in nums]
當你習慣這個寫法之後,讀起來其實比 for 迴圈更直覺,因為它的順序就是「我想要什麼 ← 從哪裡來」。
Q.列表推導式怎麼加 if 條件?
if 條件放在 for 後面就是「篩選」:
# 從 1 到 20 中只取偶數
evens = [x for x in range(1, 21) if x % 2 == 0]
也可以同時做篩選和轉換:
# 只取及格分數,並各加 5 分
scores = [55, 72, 48, 90, 63, 38]
boosted = [s + 5 for s in scores if s >= 60]
# 結果: [77, 95, 68]
Q.「篩選」的 if 和「條件式轉換」的 if-else 有什麼不同?
兩者位置和語意都不一樣:
# 篩選:if 在後面,只保留符合條件的
[x for x in range(10) if x % 2 == 0]
# 結果: [0, 2, 4, 6, 8]
# 條件式轉換:if-else 在前面,全部都要、但用條件決定值
[x if x % 2 == 0 else -1 for x in range(10)]
# 結果: [0, -1, 2, -1, 4, -1, 6, -1, 8, -1]
簡單記:只有 if → 在後面(篩選);有 if-else → 在前面(轉換)。
Q.列表推導式可以跟 map() 互相取代嗎?什麼時候用哪個?
大部分情況可以互相取代,但各有適合的場景:
- 只是套用一個現成函式(像
int、float、abs)→ 用map()比較簡潔 - 需要做運算或加條件(像
x*x、if x > 0)→ 用列表推導式比較直覺
# map() 適合
nums = list(map(int, input().split()))
# 列表推導式適合
squares = [x * x for x in nums]
evens = [x for x in nums if x % 2 == 0]
很多 APCS 高手兩種都用,看哪個寫法在當下最清楚就用哪個。
Q.列表推導式可以巢狀嗎?例如用在二維列表?
可以。常見的應用是建立二維列表:
# 建立一個 3×4 全部填 0 的二維列表
grid = [[0] * 4 for _ in range(3)]
或是把二維列表「攤平」成一維:
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flat = [x for row in matrix for x in row]
# 結果: [1, 2, 3, 4, 5, 6, 7, 8, 9]
不過巢狀寫法很容易變得難讀,如果一行寫不下就改回 for 迴圈,不要為了短而犧牲可讀性。
Q.為什麼 (x * 2 for x in nums) 不能當成列表用?
因為圓括號 () 產生的是「生成器(generator)」,不是列表。生成器只能走訪一次,而且不能像列表那樣用 len()、索引存取。
# 列表(可重複使用)
result = [x * 2 for x in nums]
# 生成器(只能跑一次,省記憶體)
result = (x * 2 for x in nums)
初學階段一律用方括號 [] 就好,等熟悉後再學生成器在處理大量資料時的優勢。
Q.列表推導式什麼時候反而不該用?
當邏輯太複雜、一行塞不下時,就該改回 for 迴圈。例如:
# 太複雜,難讀
result = [x * 2 if x > 0 else -x for x in nums if x != 0 and x % 3 == 0]
這種情況不如用幾行 for 迴圈寫清楚,程式碼是寫給人讀的,不是越短越好。判斷標準:如果同事或自己過幾天回來看,還能一眼看懂,就保留;看不懂就拆開。
相關文章
2026/5/4APCS 必學map() 函式 : 一行解決批次轉換
map()是 Python 的「批次處理工具」——一行就能把整個列表的每個元素套用同一個函式,比 for 迴圈短一半。配合int、float、abs、round,APCS 處理測資和批次運算都用得到。本篇從 for 迴圈和map()的對照寫法、三個常見用法、到map()vs 列表推導式的選用時機,帶你寫出更接近 Python 老手的程式碼。#Python#APCS#map函式
2026/5/18APCS 必學 Python 程式設計:f-string 格式化輸出
APCS 採電腦自動評分,輸出格式跟標準答案逐字元比對——多一個空格、少一個換行就拿不到分數。f-string 是 Python 3.6 之後最簡潔的字串格式化方式,能精準控制小數位數、補零、欄位對齊。本篇從 f-string 基本寫法、APCS 三大格式控制、到實戰輸出整齊成績單,幫你避免「邏輯對但格式錯」的失分。#Python#APCS#f-string
2026/5/4APCS 必學的輸入魔法第一篇:input().split()
打開 APCS 任何一份考題,幾乎每題的測資都是「一行裡好幾個數字用空格分開」。如果你還在用int(input())一個一個讀,光讀題就花光時間。input().split()是 APCS 給每位考生的第一道門檻——學會它,就跨進競賽程式的世界。本篇從新手寫法、split()的運作原理、到實戰計算平均分數,帶你一行讀完整行測資。#Python#APCS#input