2015-10-19 98 views
1

嵌套字典我有一個文本輸入,在這個格式 -創建從縮進的文本輸入

var=""" 
interface A 
    member-1 
    member-2 
    submember-1 
    submember-2 
interface B 
    member-1 
interface C 

""" 

我將不得不將其轉換成嵌套的字典形式類似下面的蟒蛇。並且任何沒有子成員的元素都被賦值爲-1。

result= 
{ 
'interface A':{'member-1': -1 ,'member-2':{'submember-1': -1,'submember-2': -1}} 
'interface B' :{'member-1': -1}, 
'interface C': -1 
} 

我試圖做一個遞歸的方式,但不似乎讓我的邏輯正確的。什麼是最好的/ pythonic的方式來做到這一點。

+0

到目前爲止您嘗試了什麼? –

+0

'我正在嘗試以遞歸的方式做<< - 向我們展示如何,所以我們可以告訴你如何解決它 – inspectorG4dget

回答

1

它有點難看,但如果u不要有太多的縮進級別的代碼可能是有用的

_dict = {} 
for line in var.split('\n'): 
    if line.strip(): 
     print line 
     leading_spaces = len(line) - len(line.lstrip()) 
     if leading_spaces == 0: 
      interface = line.strip() 
      _dict[interface] = -1 
     elif leading_spaces == 2: 
      member = line.strip() 
      if _dict[interface] == -1: 
       _dict[interface] = {member:-1} 
      else: 
       _dict[interface].update({member:-1}) 
     elif leading_spaces == 4: 
      print _dict 
      submember = line.strip() 
      if _dict[interface][member] == -1: 
       _dict[interface][member] = {submember:-1} 
      else: 
       _dict[interface][member].update({submember:-1}) 
0

遞歸是這樣的精細策略,儘管一定程度上受到的事實),你有複雜跟蹤您當前正在處理的輸入字符串中的哪一行,以及b)您必須提前查看並查看未來行的縮進級別以確定何時應該返回特定的遞歸調用。

一個解決方案是使用一個生成器來獲取連續的行,以及一個遞歸函數,該函數採用當前行和行生成器,並返回字典和「下一行」。

from collections import namedtuple 
LineData = namedtuple('LineData', 'indent text') 

def yield_linedata(text): 
    yield LineData(indent=-1, text='') 
    for line in text.split('\n'): 
     if line.strip() != '': 
      yield LineData(indent=len(line)-len(line.lstrip()), text=line.strip()) 
    yield LineData(indent=-1, text='') 

def create_dict(cur_ld, line_yielder): 
    next_ld = next(line_yielder) 
    if cur_ld.indent >= next_ld.indent: 
     return -1, next_ld  
    d = {} 
    while cur_ld.indent < next_ld.indent: 
     d[next_ld.text], next_ld = create_dict(next_ld, line_yielder) 
    return d, next_ld 

line_yielder = yield_linedata(var) 
cur_ld = next(line_yielder) 
result, next_line = create_dict(cur_ld, line_yielder) 
print result