很難搜索我無法描述的內容,因此如果其他地方已經回答了這個問題,我深表歉意。
我有一個來自 cli 工具(timewarrior,如果你熟悉的話!)的字典串列,我想將其組織成層次結構,以便列印表格或匯出 CSV。
如何生成該層次結構取決于每個串列元素中包含的串列的順序,稱為“標簽”。每個標簽串列都包含一些跟蹤時間。我想總結從下到上在層次結構上花費的時間。
這是我正在處理的資料的過度簡化示例:
data = [{"tags": ["Project A", "Task 1"], "time": 50},
{"tags": ["Project A", "Task 2"], "time": 20},
{"tags": ["Do a thing"], "time": 10},
{"tags": ["Project B", "Do a thing"], "time": 50}]
有了這些資料,我希望為遞回函式呼叫創建以下兩個結構之一:
嵌套串列:
outcome_a = [["Project A", 70, [["Task 1", 50], ["Task 2", 20]]],
["Do a thing", 10],
["Project B", 50, ["Do a thing", 50]]]
或嵌套字典:
outcome_b = {
"Project A": {
"time": 70,
"sub": {
"Task 1": {
"time": 50
},
"Task 2": {
"time": 20
}
}
},
"Do a thing": {
"time": 10
},
"Project B": {
"time": 50,
"sub": {
"Do a thing": {
"time": 50
}
}
}
}
迭代字典然后迭代里面的標簽感覺很簡單。讓我感到困惑的是,一旦迭代經過第一層嵌套資料,如何優雅地跟蹤每個元素的時間背景關系。
我顯然不想重復串列廣告并嘗試重新發現背景關系。我能想到的最佳解決方案是迭代資料并以某種方式將背景關系傳遞給下一個tags元素。我認為某種遞回函式或reducer可以做到這一點。
在這一點上,我已經抽出幾個空閑時間來考慮如何解決這個問題。我確定我想太多了。我愿意接受建議:)
uj5u.com熱心網友回復:
如果您不斷訪問它,我會避免使用嵌套的list.
如果您dict使用dict.get.
data = [{"tags": ["Project A", "Task 1"], "time": 50},
{"tags": ["Project A", "Task 2"], "time": 20},
{"tags": ["Do a thing"], "time": 10},
{"tags": ["Project B", "Do a thing"], "time": 50}]
result = {}
for tags in data:
project, *task = tags['tags']
task_time = tags['time']
if task:
result[project] = result.get(project, {'time': 0, 'sub': {}})
result[project]['sub'][task[0]] = {'time': task_time}
result[project]['time'] = task_time
else:
result[project] = {'time': task_time}
print(result)
# {
# 'Project A': {
# 'time': 70,
# 'sub': {
# 'Task 1': {'time': 50},
# 'Task 2': {'time': 20}
# }
# },
# 'Do a thing': {'time': 10},
# 'Project B': {
# 'time': 50,
# 'sub': {
# 'Do a thing': {'time': 50}
# }
# }
# }
一些亮點:
這會將密鑰解壓縮'tags'為 2 個變數。如果該鍵下僅存在一項,則將list空[]分配給task。
project, *task = tags['tags']
我們知道在這個分支中'sub'需要密鑰。dict.get()此處用于檢索project密鑰。如果它不存在,dict則為其分配一個默認結構。
result[project] = result.get(project, {'time': 0, 'sub': {}})
由于 的初始值result[project]['time']設定為0。我們可以不斷地添加到那個鍵上。
result[project]['time'] = task_time
最后,對于單個任務,什么時候task是“Falsey”。
result[project] = {'time': task_time}
編輯:
對于標簽大小不可知的東西,您可以使用相同的dict.get技巧并將其嵌套任意深度。它還具有洗掉if陳述句的額外好處。
data = [{"tags": ["Project A", "Task 1"], "time": 50},
{"tags": ["Project A", "Task 2", "Part 1"], "time": 10},
{"tags": ["Project A", "Task 2", "Part 2"], "time": 10},
{"tags": ["Do a thing"], "time": 10},
{"tags": ["Project B", "Do a thing"], "time": 50}]
result = {}
for tags in data:
project, *tasks = tags['tags']
task_time = tags['time']
result[project] = result.get(project, {'time': 0})
result[project]['time'] = task_time
current_dict = result[project]
for task in tasks:
current_dict['sub'] = current_dict.get('sub', {})
current_dict = current_dict['sub']
current_dict[task] = current_dict.get(task, {'time': 0})
current_dict[task]['time'] = task_time
current_dict = current_dict[task]
print(result)
# {
# 'Project A': {
# 'time': 70,
# 'sub': {
# 'Task 1': {'time': 50},
# 'Task 2': {
# 'time': 20,
# 'sub': {
# 'Part 1': {'time': 10},
# 'Part 2': {'time': 10}
# }
# }
# }
# },
# 'Do a thing': {'time': 10},
# 'Project B': {
# 'time': 50,
# 'sub': {
# 'Do a thing': {'time': 50}
# }
# }
# }
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/465799.html
