本文 AI 產出,尚未審核

Python 課程 – 資料結構:字串(str)

建立、索引、切片


簡介

字串(str)是程式設計中最常見的資料型別之一,無論是讀取使用者輸入、處理檔案內容,或是與外部 API 交換資料,都離不開字串的操作。
在 Python 中,字串不僅支援 Unicode,還提供了直觀且功能強大的索引與切片機制,讓開發者可以以簡潔的語法完成複雜的文字處理。

本篇文章將從 字串的建立索引切片 三個核心概念出發,結合實務範例說明其使用方式,並探討常見的陷阱與最佳實踐,最後提供幾個在日常開發中常見的應用情境,幫助讀者快速上手並寫出可靠、可讀性高的程式碼。


核心概念

1. 字串的建立

在 Python 中,字串可以使用單引號 (')、雙引號 (") 或三引號 ('''""") 包起來。
三引號常用於 多行文字文件說明文字(docstring)

# 單行字串
s1 = 'Hello, World!'
s2 = "Python is fun"

# 多行字串(保留換行與縮排)
s3 = """這是一段
跨越多行的文字,
可以直接寫在程式碼裡。"""

# 使用 raw string(避免跳脫字元被解譯)
path = r'C:\Users\Alice\Documents\file.txt'
  • 提示:若字串中同時需要單引號與雙引號,可交替使用或搭配跳脫字元(\)避免語法錯誤。
quote = "She said, \"It's a beautiful day!\""

2. 字串的索引(Indexing)

字串是 不可變(immutable) 的序列,意味著每個字元都有固定的位置(索引),且索引從 0 開始。
使用方括號 [] 即可取得單一字元。

msg = "Python 3.11"
first_char = msg[0]      # 'P'
last_char  = msg[-1]     # '1'(負索引從尾端開始算起)
second_last = msg[-2]    # '1'

2.1 取出子字元時的常見錯誤

  • 索引超出範圍msg[100] 會拋出 IndexError
  • 負索引過大msg[-100] 同樣會拋出 IndexError

解決方式:先檢查字串長度,或使用 try/except 捕捉例外。

try:
    ch = msg[100]
except IndexError:
    ch = None   # 或者給一個預設值

3. 字串的切片(Slicing)

切片讓你一次取得 連續的子字串,語法為 string[start:stop:step],其中:

參數 含義 預設值
start 起始索引(包含),可為負數 0
stop 結束索引(不包含),可為負數 字串長度
step 步長(正向或負向),若為負則反向 1

3.1 基本切片範例

txt = "abcdefghij"

# 取得第 2~5 個字元(索引 1~4)
sub1 = txt[1:5]          # 'bcde'

# 省略 start,從開頭到第 4 個字元(不含第 4 個)
sub2 = txt[:4]           # 'abcd'

# 省略 stop,從第 5 個字元到結尾
sub3 = txt[4:]           # 'efghij'

# 設定 step 為 2,取出每隔一個的字元
sub4 = txt[::2]          # 'acegi'

# 反向切片,取得字串反轉
rev = txt[::-1]          # 'jihgfedcba'

3.2 使用負索引與步長

# 取出倒數第 3 到倒數第 1 個字元(不含倒數第 0 個)
sub5 = txt[-3:-0]        # 'ij'(-0 等同於 0)

# 反向切片,從倒數第 1 個往前取三個字元
sub6 = txt[-1:-4:-1]     # 'jih'

3.3 切片的「深拷貝」概念

由於字串是不可變物件,切片本身不會產生 引用問題
即使你對切片結果再做修改(實際上是產生新字串),原字串仍保持不變:

original = "2023-08-15"
date_part = original[:10]   # '2023-08-15'
# 嘗試改變 date_part(實際上是建立新字串)
date_part = date_part.replace('-', '/')
# original 仍是原本的內容
print(original)   # 2023-08-15

常見陷阱與最佳實踐

陷阱 說明 最佳做法
忘記字串不可變 直接修改字串會拋出錯誤,或不會改變原字串 使用 replace()join() 等產生新字串
切片步長為 0 string[::0] 會產生 ValueError 步長必須是非零整數
負索引與切片起止混淆 s[-1:0] 會得到空字串,因為 stop 必須在 start 之後(正向切片) 反向切片時使用負步長 s[-1:0:-1]
使用 + 連接大量字串 會產生大量臨時字串,效能低 使用 ''.join(list_of_strings)
忽略 Unicode 正規化 不同編碼形式的相同字元會被視為不同字串 使用 unicodedata.normalize() 統一編碼

小技巧

  • 快速檢查子字串是否存在if "abc" in s:
  • 取得字串長度len(s),配合切片可避免 IndexError。
  • 字串格式化f"{name}: {value:.2f}"%format() 更直觀。

實際應用場景

  1. 日誌檔案分析
    讀取一行日誌後,只取出時間戳記與訊息等關鍵資訊:

    line = "2023-08-15 14:23:07,123 - INFO - Process started"
    timestamp = line[:23]          # '2023-08-15 14:23:07,123'
    level = line[26:30]            # 'INFO'
    message = line[33:]            # 'Process started'
    
  2. CSV 檔案欄位切割
    假設每個欄位長度固定,可直接使用切片取得:

    row = "John    Doe     03011990M"
    first_name = row[0:8].strip()   # 'John'
    last_name  = row[8:16].strip()  # 'Doe'
    birthday   = row[16:24]          # '03011990'
    gender     = row[24]            # 'M'
    
  3. 網址參數解析
    從 URL 中抽取 query string:

    url = "https://example.com/search?q=python+string&lang=zh-TW"
    query_part = url.split('?')[1]            # 'q=python+string&lang=zh-TW'
    params = dict(p.split('=') for p in query_part.split('&'))
    # {'q': 'python+string', 'lang': 'zh-TW'}
    
  4. 文字加密/解密(簡易 Caesar Cipher)
    使用切片與步長實作字母位移:

    import string
    
    alphabet = string.ascii_lowercase
    shift = 3
    # 建立加密映射表
    trans = str.maketrans(alphabet, alphabet[shift:] + alphabet[:shift])
    
    def caesar_encrypt(text):
        return text.lower().translate(trans)
    
    print(caesar_encrypt("hello world"))   # khoor zruog
    
  5. 反向顯示密碼
    為了 UI 安全,顯示最後四位,其餘以星號取代:

    pwd = "Abcdef123456"
    masked = '*' * (len(pwd) - 4) + pwd[-4:]
    print(masked)   # ********3456
    

總結

字串是 Python 最基礎、同時也是最強大的資料結構之一。透過 建立索引切片 三個核心操作,我們可以:

  • 快速取得任意子字元或子字串,不必使用迴圈或額外函式。
  • 以簡潔的語法完成文字切割、反轉、抽取固定寬度欄位,提升程式可讀性與維護性。
  • 避免常見的 IndexError、ValueError,並遵循最佳實踐(如使用 join、Unicode 正規化),寫出更安全、效能更佳的程式。

掌握這些技巧後,無論是日誌分析、檔案處理、網路爬蟲,或是簡易的加密演算法,都能以最少的程式碼完成高品質的文字處理工作。希望本篇文章能成為你在 Python 路上不可或缺的參考手冊,持續練習、探索更進階的字串方法(如正規表示式、re 模組),讓程式碼更具表現力與彈性。祝你玩得開心,寫程式更順手!