Try   HackMD

重複結構(repetition structure)

by : R緯

在 Python 中,迴圈、迭代、遍歷和遞迴是四個重要的「重複」概念。

1. 迴圈 (Loop)

  • 定義:迴圈是一種控制結構,允許你重複執行一段程式碼。Python 中最常見的迴圈有 for 迴圈和 while 迴圈。
  • 用途:用於重複執行某些操作,直到滿足特定條件。
  • 示例
    ​​for i in range(5):  # 使用 for 迴圈
    ​​    print(i)  # 輸出 0 到 4
    

2. 迭代 (Iteration)

Python 中,迭代是一種對序列中的元素進行訪問和處理的過程。每次訪問一個元素,稱為一次迭代。迭代可以使用 for 迴圈、while 迴圈等方式實現。

迭代的語法

for 變數 in 序列:
    # 處理元素的程式碼

在這個語法中,變數 是用來存放每個元素的變數,序列 是要迭代的序列。

迭代的例子

水果 = ['蘋果', '香蕉', '櫻桃']
for 水果名稱 in 水果:
    print(水果名稱)

在這個例子中,我們對水果列表進行迭代,訪問每個元素並將它印出。

迭代的優點

  • 可以對序列中的元素進行訪問和處理。
  • 可以使用 for 迴圈、while 迴圈等方式實現。
  • 可以對大型序列進行迭代。

迭代的應用

  • 對列表、元組、字串等序列中的元素進行訪問和處理。
  • 對數據庫中的資料進行訪問和處理。
  • 對文件中的資料進行訪問和處理。

3. 遍歷 (Traversal)

遍歷的基本概念

在 Python 中,遍歷是一種對數據結構中的元素進行訪問和處理的過程。每次訪問一個元素,稱為一次遍歷。遍歷可以是深度優先(depth-first)或廣度優先(breadth-first)的。

遍歷的語法

def 遍歷函數(數據結構, 節點):
    # 處理節點的程式碼
    for 子節點 in 數據結構[節點]:
        遍歷函數(數據結構, 子節點)

在這個語法中,遍歷函數 是用來遍歷數據結構的函數,數據結構 是要遍歷的數據結構,節點 是要訪問的節點。

遍歷的例子

樹 = {
    'A': ['B', 'C'],
    'B': ['D', 'E'],
    'C': ['F'],
    'D': [],
    'E': ['F'],
    'F': []
}

def 遍歷樹(樹, 節點):
    print(節點)
    for 子節點 in 樹[節點]:
        遍歷樹(樹, 子節點)

遍歷樹(樹, 'A')

在這個例子中,我們對樹進行遍歷,訪問每個節點並將它印出。

遍歷的優點

  • 可以對數據結構中的元素進行訪問和處理。
  • 可以使用遞迴函數或堆疊實現。
  • 可以對大型數據結構進行遍歷。

遍歷的應用

  • 對樹、圖等數據結構中的元素進行訪問和處理。
  • 對文件系統中的檔案進行訪問和處理。
  • 對網路中的節點進行訪問和處理。

深度優先遍歷

深度優先遍歷是一種遍歷方式,先訪問節點的子節點,然後再訪問節點本身。

廣度優先遍歷

廣度優先遍歷是一種遍歷方式,先訪問節點本身,然後再訪問節點的子節點。

遍歷的實現

遍歷可以使用遞迴函數或堆疊實現。遞迴函數是一種函數,呼叫自己來實現遍歷。堆疊是一種資料結構,使用堆疊來實現遍歷。

4. 遞迴 (Recursion)

  • 定義:遞迴是一種函數調用自身的技術。當函數需要解決一個問題時,它可以將問題分解為更小的子問題,然後調用自身來解決這些子問題。
  • 用途:用於解決可以被分解為相似子問題的問題,如計算階乘、斐波那契數列等。
  • 示例
    ​​def factorial(n):
    ​​    if n == 0:  # 基本情況
    ​​        return 1
    ​​    else:
    ​​        return n * factorial(n - 1)  # 遞迴調用
    
    ​​print(factorial(5))  # 輸出 120
    

迭代器(Iterator)

Python 迭代器是一個用於遍歷可迭代物件(如列表、元組、字典等)的工具。它允許你一次訪問一個元素,而不需要知道物件的結構或索引。

在 Python 中,任何實現了 __iter__()__next__() 方法的物件都可以被視為一個迭代器。__iter__() 方法返回迭代器物件本身,而 __next__() 方法返回下一個元素,如果沒有更多元素,則引發 StopIteration 例外。

以下是一個簡單的例子:

my_list = [1, 2, 3, 4, 5]
my_iter = iter(my_list)

print(next(my_iter))  # 輸出: 1
print(next(my_iter))  # 輸出: 2
print(next(my_iter))  # 輸出: 3
print(next(my_iter))  # 輸出: 4
print(next(my_iter))  # 輸出: 5

在這個例子中,my_list 是一個可迭代物件,my_iter 是一個迭代器物件。通過 next() 函數,可以訪問 my_list 中的每個元素。

Python 迭代器的優點包括:

  • 可以節省內存:迭代器只需要存儲當前元素的索引,而不需要存儲所有元素。
  • 可以提高效率:迭代器可以避免不必要的計算和訪問。
  • 可以實現懶加載:迭代器可以在需要時才計算下一個元素。

Python 迭代器的應用包括:

  • 遍歷列表、元組、字典等可迭代物件。
  • 實現生成器和協程。
  • 實現懶加載和延遲計算。

以下是一個使用迭代器的實際例子:

def fibonacci(n):
    a, b = 0, 1
    for _ in range(n):
        yield a
        a, b = b, a + b

for num in fibonacci(10):
    print(num)

在這個例子中,fibonacci() 函數是一個生成器,它使用迭代器返回斐波那契數列的前 10 個元素。

補充:迭代協議(Iterator Protocol)

迭代協議是一個規範,定義了如何實現迭代器和可迭代物件。

迭代協議由兩個部分組成:

  1. __iter__(): 這個方法返回迭代器物件本身。它被用於初始化迭代過程。
  2. __next__(): 這個方法返回下一個元素。如果沒有更多元素,則引發 StopIteration 例外。

任何實現了這兩個方法的物件都可以被視為一個迭代器。

以下是一個簡單的例子:

class MyIterator:
    def __init__(self, data):
        self.data = data
        self.index = 0

    def __iter__(self):
        return self

    def __next__(self):
        if self.index < len(self.data):
            result = self.data[self.index]
            self.index += 1
            return result
        else:
            raise StopIteration

my_iter = MyIterator([1, 2, 3, 4, 5])
for num in my_iter:
    print(num)

在這個例子中,MyIterator 類實現了迭代協議。它有 __iter__()__next__() 方法,分別返回迭代器物件本身和下一個元素。

Python 的可迭代物件(如列表、元組、字典等)也實現了迭代協議。這使得你可以使用迭代器遍歷這些物件。

以下是一個簡單的例子:

my_list = [1, 2, 3, 4, 5]
my_iter = iter(my_list)
for num in my_iter:
    print(num)

在這個例子中,my_list 是一個可迭代物件,my_iter 是一個迭代器物件。通過 iter() 函數,可以返回 my_list 的迭代器物件。然後,可以使用迭代器遍歷 my_list 中的元素。

map()函式

語法

map(function, iterable, ...)
  • function:要應用於每個元素的函數。
  • iterable:一個或多個可迭代對象(如列表、元組等)。如果有多個可迭代對象,則函數必須接受相同數量的參數。

返回值

map() 返回一個迭代器,你可以使用 list()tuple() 等函數將其轉換為列表或元組。

使用示例

多個可迭代對象

如果你有多個可迭代對象,可以將它們一起傳遞給 map(),函數的參數數量必須與可迭代對象的數量相同:

def add(x, y):
    return x + y

numbers1 = [1, 2, 3]
numbers2 = [4, 5, 6]
result = map(add, numbers1, numbers2)

# 將結果轉換為列表
result_list = list(result)
print(result_list)  # 輸出: [5, 7, 9]

總結

  • map() 函數可以讓你方便地對可迭代對象中的每個元素應用一個函數,並返回一個新的迭代器。