我有一個像這樣的復雜詞典串列:
data = [
{
"l_1_k": 1,
"l_1_ch": [
{
"l_2_k": 2,
"l_2_ch": [...more levels]
},
{
"l_2_k": 3,
"l_2_ch": [...more levels]
}
]
},
...more items
]
我正在嘗試將此結構展平為如下所示的行串列:
list = [
{ "l_1_k": 1, "l_2_k": 2, ... },
{ "l_1_k": 1, "l_2_k": 3, ... },
]
我需要這個串列來構建熊貓資料框。
所以,我正在為每個嵌套級別進行遞回,在最后一級我試圖附加到行串列。
def build_dict(d, row_dict, rows):
# d is the data dictionary at each nesting level
# row_dict is the final row dictionary
# rows is the final list of rows
for key, value in d.items():
if not isinstance(value, list):
row_dict[key] = value
else:
for child in value:
build_dict(child, row_dict, rows)
rows.append(row_dict) # <- How to detect the last recursion and call the append
我這樣呼叫這個函式:
rows = []
for row in data:
build_dict(d=row, row_dict={}, rows=rows)
我的問題是如果我不知道有多少嵌套級別,如何檢測這個遞回函式的最后一次呼叫。使用當前代碼,在每個嵌套級別復制該行。
或者,是否有更好的方法來獲得最終結果?
uj5u.com熱心網友回復:
在查找了一些想法之后,我想到的解決方案是這樣的:
- 宣告以下函式,取自此處:
def find_depth(d):
if isinstance(d, dict):
return 1 (max(map(find_depth, d.values())) if d else 0)
return 0
- 在您的函式中,每次深入時遞增,如下所示:
def build_dict(d, row_dict, rows, depth=0):
# depth = 1 for the beginning
for key, value in d.items():
if not isinstance(value, list):
row_dict[key] = value
else:
for child in value:
build_dict(child, row_dict, rows, depth 1)
- 最后,測驗是否達到最大深度,如果達到,則可以在函式的末尾附加它。您將需要添加一個您將呼叫的額外變數:
def build_dict(d, row_dict, rows, max_depth, depth=0):
# depth = 1 for the beginning
for key, value in d.items():
if not isinstance(value, list):
row_dict[key] = value
else:
for child in value:
build_dict(child, row_dict, rows,max_depth, depth 1)
if depth == max_depth:
rows.append(row_dict)
- 呼叫函式為:
build_dict(d=row, row_dict={}, rows=rows, max_depth=find_depth(data))
請記住,因為我沒有可以使用的資料集,其中可能存在一兩個語法錯誤,但該方法應該沒問題。
uj5u.com熱心網友回復:
我認為嘗試在函式原型中使用可變默認引數不是一個好習慣。
另外,我認為遞回回圈中的函式永遠不應該知道它所處的級別。這就是遞回的重點。相反,您需要考慮函式應該回傳什么,以及它應該何時退出遞回回圈以回傳到第 0 級。在爬回程序中,較高級別的函式呼叫處理較低級別函式呼叫的回傳值。
這是我認為可以作業的代碼。我不確定它是最佳的,就計算時間而言。
編輯:修復了 dicts 的回傳串列,而不是僅 dict
def build_dict(d):
"""
returns a list when there is no lowerlevel list of dicts.
"""
lst = []
for key, value in d.items():
if not isinstance(value, list):
lst.append([{key: value}])
else:
lst_lower_levels = []
for child in value:
lst_lower_levels.extend(build_dict(child))
new_lst = []
for elm in lst:
for elm_ll in lst_lower_levels:
lst_of_dct = elm elm_ll
new_lst.append([{k: v for d in lst_of_dct for k, v in d.items()}])
lst = new_lst
return lst
rows = []
for row in data:
rows.extend(build_dict(d=row))
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/334077.html
