【问题标题】:how to turn string into nested list with elements separated with commas如何将字符串转换为嵌套列表,其中元素用逗号分隔
【发布时间】:2019-10-22 20:18:52
【问题描述】:

我有一个如下所示的字符串:

'(a (b (c d e f)) g)'

我想把它变成这样一个嵌套列表:

['a', ['b', ['c', 'd', 'e', 'f']], 'g']

我用过这个功能:

def tree_to_list(text, left=r'[(]', right=r'[)]', sep=r','):
    pat = r'({}|{}|{})'.format(left, right, sep)
    tokens = re.split(pat, text)    
    stack = [[]]
    for x in tokens:
        if not x or re.match(sep, x): continue
        if re.match(left, x):
            stack[-1].append([])
            stack.append(stack[-1][-1])
        elif re.match(right, x):
            stack.pop()
            if not stack:
                raise ValueError('error: opening bracket is missing')
        else:
            stack[-1].append(x)
    if len(stack) > 1:
        print(stack)
        raise ValueError('error: closing bracket is missing')
    return stack.pop()

但结果不是我所期望的。字符串之间没有逗号:

['a', ['b', ['c' 'd' 'e' 'f']], 'g']

你能帮我解决一下吗

【问题讨论】:

    标签: python python-3.x string list function


    【解决方案1】:

    您可以将递归与生成器一起使用:

    import re
    data = '(a (b (c d e f)) g)'
    def group(d):
        a = next(d, ')')
        if a != ')':
            yield list(group(d)) if a == '(' else a
            yield from group(d)
    print(next(group(iter(re.findall(r'\w+|[()]', data)))))
    

    输出:

    ['a', ['b', ['c', 'd', 'e', 'f']], 'g']
    

    【讨论】:

    • 这是一个很好的方法,但我建议直接迭代字符串并添加对空格的处理,而不是使用正则表达式。无论如何 +1。
    • 这个函数去除点。例如,如果我有单词而不是字母('07.45' 而不是 'a'),它将把 '07.45' 变成 '07' '45'
    • @EdgarZakharyan 只需调整正则表达式:re.findall(r'[\w\.]+|[()]', data)
    【解决方案2】:

    使用字符串替换将输入转换为具有所需 Python 值的字符串,并使用literal_eval 将其转换为值本身:

    >>> import ast, re
    >>> data = '(a (b (c d e f)) g)'
    >>> s = re.sub(r'(\w+)', r'"\1"', data)         # quote words
    >>> s = re.sub(r'\s+', ',', s)                  # whitespace to comma
    >>> s = s.replace('(', '[').replace(')', ']')   # () -> []
    >>> ast.literal_eval(s)
    ['a', ['b', ['c', 'd', 'e', 'f']], 'g']
    

    【讨论】:

      【解决方案3】:

      人们提出了他们自己的解决方案,但您使用的代码的问题是sep 设置为正则表达式r',',它匹配单个逗号。就像您说的,您不使用逗号分隔文本,而是使用空格。如果将sep的默认值替换为r'\s',或者调用tree_to_list'(a (b (c d e f)) g)', sep=r'\s')之类的函数,那么它对我有用。

      【讨论】:

        猜你喜欢
        • 2020-12-16
        • 1970-01-01
        • 2023-04-02
        • 2013-02-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多