前言:幫助解釋爲什麼我這樣做,我將解釋最終目標。基本上,我有一個帳戶列表,這些帳戶是以非常特定的語法定義的。以下是一些示例:從Python中的多個嵌套字典/列表創建樹
Assets:Bank:Car
Assets:Bank:House
Assets:Savings:Emergency
Assets:Savings:Goals:Roof
Assets:Reserved
如上所述,帳戶可以有任意數量的父母和子女。最終目標是將上述帳戶解析爲Python中的樹狀結構,用於在Sublime Text Editor中提供帳戶自動完成功能(例如,如果我輸入Assets:然後查詢自動完成,我會與列表呈現爲這樣:銀行,儲蓄,保留)
結果:從前言使用帳戶列表,在Python期望的結果將類似於下面:
[
{
"Assets":[
{
"Bank":[
"Car",
"House"
]
},
{
"Savings":[
"Emergency",
{
"Goals":[
"Roof"
]
}
]
},
"Reserved"
]
}
]
半解決方案:我wa可以使用遞歸獲得兩個基本賬戶。這適用於添加這兩個:Assets:Bank:Car
和Assets:Bank:House
。但是,一旦他們開始有所不同,它開始崩潰,遞歸變得混亂,所以我不確定這是否是最好的方法。
import re
def parse_account(account_str):
subs = account_str.split(":")
def separate(subs):
if len(subs) == 1:
return subs
elif len(subs):
return [{subs[0]: separate(subs[1:])}]
return separate(subs)
def merge_dicts(a, b):
# a will be a list with dictionaries and text values and then nested lists/dictionaries/text values
# b will always be a list with ONE dictionary or text value
key = b[0].keys()[0] # this is the dictionary key of the only dictionary in the b list
for item in a: # item is a dictionary or a text value
if isinstance(item, dict): # if item is a dictionary
if key in item:
# Is the value a list with a dict or a list with a text value
if isinstance(b[0][key][0], str):
# Extend the current list with the new value
item[key].extend(b[0][key])
else:
# Recurse to the next child
merge_dicts(item[key], b[0][key])
else:
return a
# Accounts have an "open [name]" syntax for defining them
text = "open Assets:Bank:Car\nopen Assets:Bank:House\nopen Assets:Savings:Emergency\nopen Assets:Savings:Goals:Roof\nopen Assets:Reserved"
EXP = re.compile("open (.*)")
accounts = EXP.findall(text) # This grabs all accounts
# Create a list of all the parsed accounts
dicts = []
for account in accounts:
dicts.append(parse_account(account))
# Attempt to merge two accounts together
final = merge_dicts(dicts[0], dicts[1])
print final
# In the future we would call: reduce(merge_dicts, dicts) to merge all accounts
我可能會以完全錯誤的方式解決這個問題,我會對不同的意見感興趣。否則,是否有人知道如何使用示例字符串中的其餘帳戶進行此項工作?
你所需的輸出將給予'SyntaxError'('Reserved'是一個沒有價值的關鍵)。 – mgilson
我很抱歉,我把輸出粘貼爲:'print json.dumps(final)',以使它更易於辨別。 –