我有一个文本输入,格式为
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
}
我试图以递归方式进行,但似乎没有让我的逻辑正确。什么是最佳/ pythonic方式来做到这一点。
答案 0 :(得分: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})
答案 1 :(得分:0)
递归对于这样的事情来说是一个很好的策略,虽然有点复杂,因为a)你必须跟踪你当前正在处理的输入字符串中的哪一行,并且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