本文 AI 產出,尚未審核

Python 課程 – 檔案操作(File I/O)

主題:CSV 檔案處理(csv 模組)


簡介

在資料分析、網站爬蟲、或是系統整合的過程中,CSV(Comma‑Separated Values) 是最常見的資料交換格式之一。它以純文字方式儲存表格資料,兼容性極高,幾乎所有程式語言與辦公軟體(如 Excel、Google Sheet)都能直接讀寫。
Python 內建的 csv 模組 提供了簡潔且安全的 API,讓開發者不必自行處理字元分割、跳脫字元或換行問題。即使是剛踏入程式領域的初學者,也能在短時間內掌握 CSV 的讀寫技巧,並把它應用在日常工作或專案中。

本篇文章將從 核心概念實作範例常見陷阱與最佳實踐,到 實際應用場景,一步步帶你完整了解如何使用 csv 模組進行檔案操作。


核心概念

1. csv 模組的基本結構

csv 主要提供兩組函式:

功能 常用函式 說明
讀取 csv.readercsv.DictReader 逐行讀取 CSV,前者回傳 list,後者回傳 dict(以表頭為鍵)
寫入 csv.writercsv.DictWriter 逐行寫入 CSV,前者接受 list,後者接受 dict(自動對應欄位)

Tip:在開啟檔案時務必使用 newline='',避免 Windows 系統自動加入多餘的換行符號。

2. 讀取 CSV:csv.reader

import csv

# 讀取範例 CSV,假設檔名為 data.csv
with open('data.csv', newline='', encoding='utf-8') as f:
    reader = csv.reader(f)          # 建立 reader 物件
    for row in reader:              # 逐行遍歷
        print(row)                  # 每一列是一個 list
  • row 會是一個 list,其中的每個元素對應欄位值。
  • 若檔案使用非預設分隔符(如分號 ;),可以透過 delimiter 參數調整:
reader = csv.reader(f, delimiter=';')

3. 讀取 CSV:csv.DictReader

import csv

with open('data.csv', newline='', encoding='utf-8') as f:
    dict_reader = csv.DictReader(f)   # 以表頭建立鍵值對
    for record in dict_reader:
        # 直接以欄位名稱存取資料
        print(f"姓名: {record['Name']}, 年齡: {record['Age']}")
  • DictReader 會自動把第一列視為 欄位名稱,之後每一列會被轉成 dict
  • 若 CSV 沒有表頭,可自行傳入 fieldnames
dict_reader = csv.DictReader(f, fieldnames=['Name', 'Age', 'City'])

4. 寫入 CSV:csv.writer

import csv

rows = [
    ['Name', 'Age', 'City'],
    ['Alice', 30, 'Taipei'],
    ['Bob', 25, 'Kaohsiung']
]

with open('output.csv', 'w', newline='', encoding='utf-8') as f:
    writer = csv.writer(f)
    writer.writerows(rows)   # 一次寫入多列
  • writerow() 可寫入單列,writerows() 可一次寫入多列。
  • 若要自訂分隔符或引用字元,可使用 delimiterquotecharquoting 等參數:
writer = csv.writer(f, delimiter=';', quotechar='"', quoting=csv.QUOTE_MINIMAL)

5. 寫入 CSV:csv.DictWriter

import csv

fieldnames = ['Name', 'Age', 'City']
data = [
    {'Name': 'Charlie', 'Age': 28, 'City': 'Tainan'},
    {'Name': 'Diana', 'Age': 32, 'City': 'Taichung'}
]

with open('output_dict.csv', 'w', newline='', encoding='utf-8') as f:
    dict_writer = csv.DictWriter(f, fieldnames=fieldnames)
    dict_writer.writeheader()          # 先寫入表頭
    dict_writer.writerows(data)        # 寫入多筆資料
  • writeheader() 會自動產生欄位名稱列。
  • 若字典缺少某些欄位,DictWriter 會以 空字串 填補;若有多餘欄位則會被忽略。

6. 處理特殊字元:quotingescapechar

CSV 中若欄位值本身包含分隔符(如逗號)或換行,必須使用 引號 包住。csv 模組提供四種 quoting 模式:

常數 行為
csv.QUOTE_ALL 所有欄位皆加引號
csv.QUOTE_MINIMAL 只在必要時加引號(預設)
csv.QUOTE_NONNUMERIC 非數值欄位加引號
csv.QUOTE_NONE 完全不加引號,需自行指定 escapechar

範例:

with open('complex.csv', 'w', newline='', encoding='utf-8') as f:
    writer = csv.writer(f, quoting=csv.QUOTE_ALL)
    writer.writerow(['Item', 'Description'])
    writer.writerow(['Book', 'Python, 程式設計\n入門指南'])

輸出會自動在含有逗號與換行的欄位加上雙引號,確保 CSV 結構不被破壞。


常見陷阱與最佳實踐

陷阱 可能的結果 解決方案
未使用 newline='' 開檔 Windows 會產生空白行(\\r\\n\\r\\n open(..., newline='') 為必備寫法
編碼不一致(如 UTF‑8 vs. Big5) 讀取時出現 UnicodeDecodeError 或亂碼 明確指定 encoding='utf-8'(或目標編碼)
分隔符錯誤(預設逗號) 讀取結果變成單一欄位 使用 delimiter=';'delimiter='\t' 等正確參數
欄位名稱大小寫不一致(DictReader) KeyError .lower() 正規化欄位名稱或使用 fieldnames 重新映射
寫入時忘記 writeheader()(DictWriter) 輸出檔缺少表頭,後續讀取不易 記得呼叫 writeheader(),或自行寫入表頭列
大量資料一次讀入造成記憶體吃緊 程式卡頓或 OOM 使用 生成器(逐行處理)或 pandas.read_csv 搭配 chunksize

建議的寫法範本

def read_csv(filepath, *, delimiter=',', encoding='utf-8'):
    """逐行讀取 CSV,返回 generator,適合大檔案。"""
    with open(filepath, newline='', encoding=encoding) as f:
        reader = csv.reader(f, delimiter=delimiter)
        for row in reader:
            yield row
  • 透過 generatoryield)可以一次只保留一列資料於記憶體,避免 OOM。

實際應用場景

  1. 資料匯入/匯出

    • 企業系統常以 CSV 與 ERP、CRM 交換客戶或訂單資料。使用 csv.DictReader 直接把每筆訂單轉成字典,便於後續驗證與寫入資料庫。
  2. 批次報表產生

    • 透過 csv.writer 產生每日銷售報表,結合 datetime 自動命名檔案,讓業務團隊可即時下載。
  3. 簡易 API 回傳

    • 某些內部服務需要把搜尋結果以 CSV 格式回傳給前端或第三方系統,只要把 listdict 直接寫入 StringIO,再回傳文字流即可。
    import csv, io
    
    def generate_csv(data):
        output = io.StringIO()
        writer = csv.DictWriter(output, fieldnames=['id', 'value'])
        writer.writeheader()
        writer.writerows(data)
        return output.getvalue()
    
  4. 資料清理與轉換

    • 讀取舊系統的 CSV 檔,使用 DictReader 逐列檢查欄位格式,修正錯誤後再以 DictWriter 輸出成新檔,完成資料遷移。

總結

  • CSV 是最通用的表格資料格式,Python 的 csv 模組 提供了 reader / DictReaderwriter / DictWriter 四大核心 API,讓讀寫操作變得安全且易於維護。
  • 正確使用 newline=''、指定 encoding、以及根據實際需求調整 delimiterquoting 等參數,能避免大多數常見錯誤。
  • 透過 generator分批處理,即使面對百萬筆資料也不會耗盡記憶體。
  • 在企業報表、資料匯入/匯出、簡易 API 等多種情境下,熟練 CSV 處理技巧將大幅提升開發效率與資料品質。

掌握了本文的概念與範例,你就能在 Python 中自信地操作 CSV 檔案,將原始資料快速轉換成有用的資訊,為後續的分析或系統整合奠定堅實基礎。祝你寫程式愉快!