遞迴(Recursion)是 Python 非常強大的技巧,能夠讓你輕鬆解決巢狀結構的資料處理問題。
本篇用「抽取類似 AST(抽象語法樹)中的所有標題」這個經典例子,手把手帶你認識遞迴函數的寫法與思考方式!
基本概念
在許多樹狀、巢狀資料結構中(像 HTML、JSON、markdown AST),
「標題」可能出現在任何一層。
我們的目標:
找出所有
"type": "heading"
的節點,並把它們的標題文字收集起來。
超簡化 AST 範例
假設我們的資料長這樣:
node = {
"type": "root",
"children": [
{
"type": "heading",
"attrs": {"level": 2},
"children": [
{"type": "text", "raw": "第一章 標題"}
]
},
{
"type": "paragraph",
"children": [
{"type": "text", "raw": "一些段落"}
]
},
{
"type": "heading",
"attrs": {"level": 3},
"children": [
{"type": "text", "raw": "第一章小節"}
]
},
{
"type": "section",
"children": [
{
"type": "heading",
"attrs": {"level": 2},
"children": [
{"type": "text", "raw": "第二章 標題"}
]
}
]
}
]
}
- 這個結構有多層巢狀,標題可能藏在 section 裡面。
node: Dict[“children”,list]
node是一個dict,有”children” 這個key,取值後為list
list的內容又是Dict[“children”,list]….
可能還會有更深層重複的結構
遞迴解法:抓出所有標題
我們要寫一個遞迴函數,自動走訪每一層 children,
遇到 "type": "heading"
就取出標題文字。
def extract_titles(node, titles=None):
if titles is None:
titles = []
# 如果這個節點是 heading,就抓標題文字
if isinstance(node, dict) and node.get("type") == "heading":
# 找到第一個 type=text 的 raw
for child in node.get("children", []):
if child.get("type") == "text":
titles.append(child.get("raw", ""))
break # 假設只取第一個文字
# 如果這個節點有 children,就遞迴處理每個 child
for child in node.get("children", []):
extract_titles(child, titles)
return titles
一步步說明
- 檢查節點型態:如果是 heading,就抓標題文字。
- 遞迴 children:如果節點有 children,就對每個 child 再呼叫自己(這就是遞迴!)。
- 累積結果:把標題都放進
titles
清單。
實際執行

推薦hahow線上學習python: https://igrape.net/30afN
近期留言