for
迴圈 (For Loop)
for
迴圈是程式設計中不可或缺的工具,它讓重複執行特定任務變得簡單高效。Python 的 for
迴圈尤其強大且靈活,支援多種迭代方式。這篇文章將帶你深入了解 Python for
迴圈的各種用法,從基礎概念到進階技巧,包括 range()
, enumerate()
, 迭代器 (iterators) 和生成器 (generators)。
1. 什麼是 for
迴圈?
for
迴圈用於遍歷序列(例如列表、元組、字典、集合或字串)或其他可迭代物件 (iterable objects) 中的每個項目。它的基本語法如下:
for item in iterable:
# 執行某些操作 (do something with item)
print(item)
iterable
: 任何可以一次返回一個成員的物件。item
: 在每次迭代中,從iterable
中取出的當前項目。
例如,遍歷一個水果列表:
fruits = ["蘋果", "香蕉", "橙"]
for fruit in fruits:
print(f"我喜歡吃 {fruit}")
輸出:
我喜歡吃 蘋果
我喜歡吃 香蕉
我喜歡吃 橙
2. 遍歷不同類型的序列
for
迴圈可以輕鬆遍歷 Python 中常見的序列類型。
2.1. 遍歷列表 (Lists)
列表是最常用的可迭代物件之一。
numbers = [1, 2, 3, 4, 5]
for num in numbers:
print(f"數字: {num}")
2.2. 遍歷元組 (Tuples)
元組與列表類似,但其內容不可更改。
colors = ("紅色", "綠色", "藍色")
for color in colors:
print(f"顏色: {color}")
2.3. 遍歷字串 (Strings)
字串是字符的序列,也可以使用 for
迴圈遍歷。
message = "Hello"
for char in message:
print(f"字母: {char}")
2.4. 遍歷字典 (Dictionaries)
字典 (Dictionaries) 是一種鍵值對 (key-value pair) 的集合。遍歷字典時,有多種方式可以獲取其內容。
預設情況下,遍歷字典會得到它的鍵 (keys):
my_dict = {"name": "Alice", "age": 30, "city": "New York"}
print("遍歷字典的鍵:")
for key in my_dict:
print(f"鍵: {key}, 值: {my_dict[key]}")
輸出:
遍歷字典的鍵:
鍵: name, 值: Alice
鍵: age, 值: 30
鍵: city, 值: New York
注意:在 Python 3.7+ 中,字典會保持插入順序。在更早的版本中,遍歷順序是不確定的。
遍歷字典的值 (values): 如果你只需要字典中的值,可以使用 .values()
方法。
my_dict = {"name": "Alice", "age": 30, "city": "New York"}
print("\n遍歷字典的值:")
for value in my_dict.values():
print(f"值: {value}")
輸出:
遍歷字典的值:
值: Alice
值: 30
值: New York
遍歷字典的鍵值對 (key-value pairs): 如果你需要同時獲取鍵和值,最常用的方法是使用 .items()
方法,它會返回一個包含 (鍵, 值) 元組的視圖物件。
my_dict = {"name": "Alice", "age": 30, "city": "New York"}
print("\n遍歷字典的鍵值對:")
for key, value in my_dict.items():
print(f"鍵: {key}, 值: {value}")
輸出:
遍歷字典的鍵值對:
鍵: name, 值: Alice
鍵: age, 值: 30
鍵: city, 值: New York
這種方式通常比直接遍歷鍵然後再用鍵去查找值更清晰且可能更高效。
3. range()
函數:數字序列的好幫手
當你需要遍歷一個數字序列時,range()
函數非常有用。它會生成一個不可變的數字序列。
range(stop)
生成從 0 開始到 stop-1
的數字。
for i in range(5): # 生成 0, 1, 2, 3, 4
print(i)
range(start, stop)
生成從 start
開始到 stop-1
的數字。
for i in range(2, 6): # 生成 2, 3, 4, 5
print(i)
range(start, stop, step)
生成從 start
開始,每次增加 step
,直到(但不包括)stop
的數字。
for i in range(1, 10, 2): # 生成 1, 3, 5, 7, 9
print(i)
range()
通常與 for
迴圈結合使用,執行特定次數的操作或基於索引訪問列表元素(雖然 enumerate()
通常是更好的選擇)。
# 執行某操作 3 次
for _ in range(3): # _ 是一個常用變數名,表示我們不在乎這個值
print("執行操作")
4. enumerate()
函數:同時獲取索引和值
有時,在遍歷序列時,你既需要項目本身,也需要該項目的索引。傳統做法可能如下:
my_list = ["a", "b", "c"]
index = 0
for item in my_list:
print(f"索引: {index}, 值: {item}")
index += 1
或者使用 range(len(my_list))
:
my_list = ["a", "b", "c"]
for i in range(len(my_list)):
print(f"索引: {i}, 值: {my_list[i]}")
Python 提供了更簡潔的方式:enumerate()
函數。它返回一個包含 (索引, 值) 元組的枚舉物件。
my_list = ["a", "b", "c"]
for index, item in enumerate(my_list):
print(f"索引: {index}, 值: {item}")
輸出:
索引: 0, 值: a
索引: 1, 值: b
索引: 2, 值: c
你還可以指定索引起始值:
my_list = ["a", "b", "c"]
for index, item in enumerate(my_list, start=1): # 索引從 1 開始
print(f"項目 #{index}: {item}")
輸出:
項目 #1: a
項目 #2: b
項目 #3: c
enumerate()
使代碼更 Pythonic 且易於閱讀。
5. 迭代器 (Iterator) 與可迭代物件 (Iterable)
理解迭代器和可迭代物件有助於更深入地了解 for
迴圈的工作原理。
5.1. 可迭代物件 (Iterable)
一個可迭代物件是任何可以從中獲取迭代器的物件。簡單來說,任何你可以用 for ... in ...
語句遍歷的物件都是可迭代的。例如:列表、字串、元組、字典、集合、range()
物件、檔案等。 技術上,如果一個物件實現了 __iter__()
方法(返回一個迭代器)或 __getitem__()
方法(支持索引訪問),它就是可迭代的。
5.2. 迭代器 (Iterator)
一個迭代器是一個表示數據流的物件。它記住其在迭代過程中的位置。迭代器實現了 __next__()
方法,該方法返回序列中的下一個項目。當沒有更多項目時,它會引發 StopIteration
異常。 你可以使用內建函數 iter()
從可迭代物件中獲取迭代器。
my_list = [10, 20, 30]
my_iterable = my_list # my_list 是一個可迭代物件
my_iterator = iter(my_list) # 從 my_list 獲取迭代器
print(type(my_iterable)) # <class 'list'>
print(type(my_iterator)) # <class 'list_iterator'>
print(next(my_iterator)) # 輸出: 10
print(next(my_iterator)) # 輸出: 20
print(next(my_iterator)) # 輸出: 30
# print(next(my_iterator)) # 如果再次調用,會引發 StopIteration 異常
for
迴圈在內部就是這樣工作的:
- 它首先調用可迭代物件的
iter()
方法獲取一個迭代器。 - 然後,它重複調用迭代器的
next()
方法獲取每個項目。 - 當
next()
引發StopIteration
異常時,迴圈終止。
6. 生成器 (Generator):高效處理大量數據
生成器是一種特殊的迭代器,但它們的創建方式更簡單,並且在處理大量數據或無限序列時非常高效。
6.1. 什麼是生成器?
生成器允許你聲明一個行為類似迭代器的函數。它們使用 yield
關鍵字返回值。每次在生成器上調用 next()
時,它會從上次離開的地方繼續執行,直到遇到下一個 yield
語句。生成器是「惰性求值」的,這意味著它們只在需要時才生成值,從而節省記憶體。
6.2. 生成器函數 (Generator Functions)
一個包含 yield
語句的函數自動成為一個生成器函數。調用生成器函數會返回一個生成器物件(一種迭代器)。
def simple_generator():
print("生成器開始")
yield 1
print("繼續...")
yield 2
print("再次繼續...")
yield 3
print("生成器結束")
# 獲取生成器物件
my_gen = simple_generator()
# 遍歷生成器
for value in my_gen:
print(f"接收到值: {value}")
輸出:
生成器開始
接收到值: 1
繼續...
接收到值: 2
再次繼續...
接收到值: 3
生成器結束
生成器非常適合處理大型檔案或數據流,因為它們不需要一次將所有數據載入記憶體。
6.3. 生成器表達式 (Generator Expressions)
生成器表達式提供了一種創建簡單生成器的簡潔語法,類似於列表推導式 (list comprehensions),但使用圓括號 ()
而不是方括號 []
。
# 列表推導式 (創建列表,佔用記憶體)
squares_list = [x*x for x in range(5)]
print(squares_list) # [0, 1, 4, 9, 16]
# 生成器表達式 (創建生成器,惰性求值)
squares_gen = (x*x for x in range(5))
print(squares_gen) # <generator object <genexpr> at 0x...>
for num in squares_gen:
print(num) # 逐個輸出 0, 1, 4, 9, 16
7. 迴圈控制陳述式 (Loop Control Statements)
Python 提供了幾個陳述式來控制迴圈的執行流程。
7.1. break
:提前終止迴圈
break
陳述式用於立即退出當前所在的 for
或 while
迴圈。
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
for num in numbers:
if num > 5:
print("找到大於 5 的數字,迴圈終止。")
break # 退出迴圈
print(num)
輸出:
1
2
3
4
5
找到大於 5 的數字,迴圈終止。
7.2. continue
:跳過目前迭代
continue
陳述式用於跳過迴圈中 continue
之後的剩餘代碼,並直接進入下一次迭代。
numbers = [1, 2, 3, 4, 5]
for num in numbers:
if num % 2 == 0: # 如果是偶數
print(f"跳過偶數: {num}")
continue # 跳到下一次迭代
print(f"處理奇數: {num}")
輸出:
處理奇數: 1
跳過偶數: 2
處理奇數: 3
跳過偶數: 4
處理奇數: 5
7.3. for...else
:迴圈正常結束時執行
for
迴圈可以有一個可選的 else
子句。如果迴圈遍歷完所有項目(即沒有被 break
陳述式中斷),則 else
子句中的代碼將被執行。
my_list = [1, 3, 5] # 列表中的所有數字都是奇數
for num in my_list:
if num % 2 == 0:
print(f"找到偶數: {num}")
break
else: # 只有在迴圈正常結束 (沒有 break) 時執行
print("列表中沒有偶數。")
my_list_with_even = [1, 2, 5]
for num in my_list_with_even:
if num % 2 == 0:
print(f"找到偶數: {num}")
break
else:
print("列表中沒有偶數。")
輸出:
列表中沒有偶數。
找到偶數: 2
8. 巢狀迴圈 (Nested Loops)
你可以在一個 for
迴圈內部放置另一個 for
迴圈,這稱為巢狀迴圈。這對於處理二維數據結構(如矩陣或列表的列表)非常有用。
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
for row in matrix: # 外層迴圈
for item in row: # 內層迴圈
print(item, end=" ") # end=" " 讓輸出在同一行,以空格分隔
print() # 每處理完一行後換行
輸出:
1 2 3
4 5 6
7 8 9
使用巢狀迴圈時要注意效率,因為執行次數是外層迴圈次數乘以內層迴圈次數。
9. 總結與選擇
for
迴圈是 Python 中一個非常強大的工具,用於迭代各種數據結構。
- 基本遍歷:直接遍歷列表、元組、字串、字典(鍵、值或鍵值對)等。
range()
:當你需要迭代特定次數或生成數字序列時使用。enumerate()
:當你同時需要索引和值時,這是最 Pythonic 的方式。- 迭代器 (Iterators):理解
for
迴圈背後的核心機制。 - 生成器 (Generators):用於創建迭代器,尤其適用於處理大量數據或無限序列,能有效節省記憶體。
- 迴圈控制:
break
,continue
, 和else
子句提供了對迴圈流程的精細控制。
掌握這些 for
迴圈的變體和相關工具,將使你的 Python 編程更加高效和優雅。