2015-10-19 51 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