首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将python字符串转换为树结构:继续

将python字符串转换为树结构:继续
EN

Stack Overflow用户
提问于 2015-08-24 18:41:29
回答 1查看 226关注 0票数 0

Here is where the question started

用这个问题的最上面的答案,我能得到一些有用的东西。但现在有了一个小小的修改。我得到的数据格式如下:

代码语言:javascript
复制
key (metadata) = value

如果有一个具有子行的行,则值将为空,并将引用下面的行,如下所示:

代码语言:javascript
复制
    key-0 (meta) = 0
    key-1 (meta) =
        key-11 (meta) = 1
        key-12 (meta) = 
            key-121 (meta = 2
        key-13 (meta) = 3
    key-2 (meta) = 4
    key-3 (meta) = 
        key-31 (meta) = 5

等等,钥匙永远不会有空位。我需要的是以下树结构:

代码语言:javascript
复制
  {
    'key-0': ['0'],
    'key-1': {
      'key-11': ['1'], 
      'key-12': {
        'key-121': ['2']
      }, 
      'key-13': ['3']
    },
    'key-2': ['4'],
    'key-3': {
      'key-31': ['5']
    }
  }

这是我拥有的

代码语言:javascript
复制
def parse_message_to_tree(message):
    firstline = message.split('\n', 1)[0]
    prefix = len(firstline) - len(firstline.lstrip())
    buf = StringIO(message)
    return parse_message_to_tree_helper(buf, prefix, None)[0]

def parse_message_to_tree_helper(buf, prev, prevline):
    ret = {}
    index = -1
    for line in buf:
        line = line.rstrip()
        index = len(line) - len(line.lstrip())
        if index > prev:
            key = prevline.split()[0]
            val = prevline.split('=')[-1]
            ret[key],prevline,index = parse_message_to_tree_helper(buf, index, line)
            if index < prev:
                return ret,prevline,index
            continue
        elif not prevline:
            key = line.split()[0]
            value = line.split('=')[-1]
            if key not in ret:
                ret[key] = []
            ret[key].append(value.strip())            
        else:
            key = prevline.split()[0]
            value = prevline.split('=')[-1]
            if key not in ret:
                ret[key] = []
            ret[key].append(value.strip())
        if index < prev:
            return ret,line,index
        prevline = line
    if index == -1 and prevline:
        key = prevline.split()[0]
        value = prevline.split('=')[-1]
        if key not in ret:
            ret[key] = []
        ret[key].append(value.strip())
        return ret,index, None
    if prev == index and prevline:
        key = prevline.split()[0]
        value = prevline.split('=')[-1]
        if key not in ret:
            ret[key] = []
        ret[key].append(value.strip())
    return ret,0,None

这通常是可行的,只有一个问题。当第一行没有任何子行时(如示例中所示),它的值将在dict中重复:

代码语言:javascript
复制
>>> pprint.pprint(parse_message_to_tree(test))
{'key-0': ['0', '0'],
 'key-1': {'key-11': ['1'], 'key-12': {'key-121': ['2']}, 'key-13': ['3']},
 'key-2': ['4'],
 'key-3': {'key-31': ['5']}}

我也搞不懂为什么。

编辑:这个问题可以通过在我追加之前添加一个检查来解决:

代码语言:javascript
复制
if value.strip() not in ret[key]:
  ret[key].append(value.strip())

但我还是想弄清楚为什么会发生这种事。控制流中一定有一个漏洞,但我找不到。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-08-24 19:17:24

您提供的解决方案确实有效,但并不能解决最初的问题。这只是一个简单的解决办法。正在发生的事情是,你在第一行重复。这两起案件:

代码语言:javascript
复制
    elif not prevline:
        key = line.split()[0]
        value = line.split('=')[-1]
        if key not in ret:
            ret[key] = []
        ret[key].append(value.strip())            
    else:
        key = prevline.split()[0]
        value = prevline.split('=')[-1]
        if key not in ret:
            ret[key] = []
        ret[key].append(value.strip())

做同样的事。您可以通过将elif更改为以下内容来解决此问题:

代码语言:javascript
复制
elif not prevline:
    prevline = line
    continue

或者,您可以完全摆脱elif,只需在第一个方法中使用if else并传入prevline值。

代码语言:javascript
复制
def parse_message_to_tree(message):
    msg = message.split('\n', 1)
    firstline = msg[0]
    prefix = len(firstline) - len(firstline.lstrip())
    buf = StringIO(msg[1])
    return parse_message_to_tree_helper(buf, prefix, firstline)[0]
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32189433

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档