Python 从缩进文本输入创建嵌套字典

Python 从缩进文本输入创建嵌套字典,python,Python,我有一个这种格式的文本输入- var=""" interface A member-1 member-2 submember-1 submember-2 interface B member-1 interface C """ 我必须将其转换为python嵌套字典形式,如下所示。而且,任何没有子成员的元素都将被赋值为-1 result= { 'interface A':{'member-1': -1 ,'member-2':{'submember-1': -1,'

我有一个这种格式的文本输入-

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

"""
我必须将其转换为python嵌套字典形式,如下所示。而且,任何没有子成员的元素都将被赋值为-1

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

我试图用递归的方式来做,但我的逻辑似乎不正确。做这件事最好的方法是什么

这有点难看,但是如果你没有太多的缩进级别,这段代码可能会很有用

_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})

递归对于这样的事情来说是一种很好的策略,尽管有点复杂,因为a)您必须跟踪当前正在处理的输入字符串中的哪一行,b)您必须向前看,查看未来行的缩进级别,以确定特定递归调用何时应返回

一种解决方案是使用生成器获得连续的行,使用递归函数获取当前行和行生成器,并返回字典和“下一行”

从集合导入namedtuple
LineData=namedtuple('LineData','indent text')
def产量线数据(文本):
产量线数据(缩进=-1,文本=“”)
对于text.split('\n')中的行:
如果line.strip()!='':
屈服线数据(缩进=len(line)-len(line.lstrip()),text=line.strip())
产量线数据(缩进=-1,文本=“”)
定义创建目录(当前行):
下一行=下一行
如果当前缩进>=下一个缩进:
返回-1,下一个\u ld
d={}
当前缩进<下一缩进:
d[next_ld.text],next_ld=create_dict(next_ld,line_yielder)
返回d,下一个
行=收益率行数据(var)
cur\u ld=下一行(第二行)
结果,下一行=创建目录(当前,行)
打印结果

到目前为止您尝试了什么?
我正在尝试以递归的方式来完成它
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