在處理 JSON 或設定檔時,資料通常不是只有一層,而是由:
dictlist- 純量,例如
str、int、bool、None
互相巢狀組成。
例如:
data = {
"steps": [
{
"class_name": "LoginStep",
"action": {
"bypass": False
}
},
{
"class_name": "NetworkStep",
"action": {
"bypass": True
},
"children": [
{
"class_name": "PingStep",
"action": {
"bypass": False
}
}
]
}
],
"metadata": {
"owner": "QA",
"version": 2
}
}我們希望:
- 遍歷所有巢狀的
dict與list; - 找出具有
class_name的節點; - 依照
action["bypass"]分成 Active 與 Bypass; - 同時記錄節點路徑。
一、遞迴的核心概念
遞迴函式就是:
函式在處理目前資料時,再呼叫自己處理子資料。
基本形式如下:
def traverse(node):
if node 是容器:
for child in node:
traverse(child)遞迴一定要有兩個部分:
1. 繼續條件
遇到可以繼續展開的容器:
dict
list就繼續呼叫 traverse()。
2. 終止條件
遇到沒有子節點的資料:
str
int
float
bool
None就停止目前這條路徑。
if not isinstance(node, (dict, list)):
return這個 return 就是遞迴的終止條件。
二、先看最簡單的遞迴版本
def simple_traverse(node):
if isinstance(node, dict):
for key, value in node.items():
simple_traverse(value)
elif isinstance(node, list):
for item in node:
simple_traverse(item)
else:
return它的邏輯是:

其實純量的 else 也可以省略:
def simple_traverse(node):
if isinstance(node, dict):
for value in node.values():
simple_traverse(value)
elif isinstance(node, list):
for item in node:
simple_traverse(item)因為當 node 不是 dict 也不是 list 時,函式會自然走到結尾,自動回傳:
return None但在正式程式中,明確寫出:
if not isinstance(node, (dict, list)):
return會更容易表達:
純量是遞迴的終止點。
三、最重要的觀念:每次遞迴都是一次新的函式呼叫
假設程式執行:
traverse(data, "root")遇到子節點時:
traverse(value, child_path)這會建立另一個新的 traverse() 呼叫。
可以想成:
第 1 次呼叫:處理 root
第 2 次呼叫:處理 root | steps
第 3 次呼叫:處理 root | steps | 0每一次呼叫都有自己的:
nodepath- 執行位置
- 回傳位置
所以在某一層執行:
return只會結束:
目前這一次
traverse()呼叫。
它會回到上一層,而不是直接消滅所有遞迴層級。
四、return 結束的是分支,不是整個遞迴
請看這個資料:
data = {
"e": None,
"a": {
"b": [1, 2, {"c": 3}],
"d": "hello"
}
}呼叫:
traverse(data, "root")第一層是字典,因此程式執行:
for key, value in data.items():
traverse(value, child_path)先處理:
"e": None等同於呼叫:
traverse(None, "root | e")因為 None 是純量:
if not isinstance(None, (dict, list)):
return這個 return 的意思是:
結束 traverse(None, "root | e")



![Python TQC 510 費氏數列,list[], f.append(n3) Python TQC 510 費氏數列,list[], f.append(n3)](https://i2.wp.com/savingking.com.tw/wp-content/uploads/2022/04/20220522152013_66.jpg?quality=90&zoom=2&ssl=1&resize=350%2C233)






近期留言