Home > database >  How to convert a nested list in string format to a list (recursively or in an iterative way)
How to convert a nested list in string format to a list (recursively or in an iterative way)

Time:11-06

I have this string "[1,[2,3],[4,5,6],[7,[8,90],10],[11,120,[13]]]" as an input. How can I convert this string to a list by using recursion or iteration but no imports in Python?

This is what I have tried. This solution only worked for the string "[1,[2,3]]" part of my input.

The expected output is the [1,[2,3],[4,5,6],[7,[8,90],10],[11,120,[13]]]

l = "[1,[2,3],[4,5,6],[7,[8,90],10],[11,120,[13]]]"

def convert(l,out=[],i=0):
    while i<len(l)-1:
        if l[i] == "]":
            return out,i
        if l[i] =="[":
            out_to_add,index = convert(l[i 1:],[])
            out.append(out_to_add)
            i =index
        elif l[i]!=",":
            out.append(l[i])
        i =1
print(convert(l)[0][0])

edit: NB. this is an assignment and not imports are allowed

CodePudding user response:

keeping nesting level

Use ast.literal_eval:

from ast import literal_eval

l = "[1,[2,3],[4,5,6],[7,[8,90],10],[11,120,[13]]]"
literal_eval(l)

output: [1, [2, 3], [4, 5, 6], [7, [8, 90], 10], [11, 120, [13]]]

flat list

Use a regex, get rid of all the brackets and split:

import re
l = "[1,[2,3],[4,5,6],[7,[8,90],10],[11,120,[13]]]"
re.sub('[][]', '', l).split(',')

output: ['1', '2', '3', '4', '5', '6', '7', '8', '90', '10', '11', '120', '13']

for ints:

list(map(int, re.sub('[][]', '', l).split(',')))

output: [1, 2, 3, 4, 5, 6, 7, 8, 90, 10, 11, 120, 13]

CodePudding user response:

The following solution allows you to get what you need without any import (the solution is essentially based on scanning characters one by one, taking actiona accordingly):

l = "[1,[2,3],[4,5,6],[7,[8,90],10],[11,120,[13]]]"

def list_parse(s):
    open_lists = []
    current_number = ""
    for c in s:
        if c == "[":
            current_list = []
            open_lists.append(current_list)
        elif c in "0123456789":
            current_number  = c
            continue
        elif c == "," or c == "]":
            if len(current_number) > 0:
                current_list.append(int(current_number))
            current_number = ""
            if c == "]":
                ll = open_lists.pop()
                if len(open_lists) == 0:
                    return ll
                else:
                    current_list = open_lists[-1]
                    current_list.append(ll)
    raise ValueError("Check that the passed list is well formed (are all the parenthesis matched?)")

try:
    print(list_parse(l))
except ValueError as e:
    print(e)

From the few tests I have run with a badly formed input l (unmatched parenthesis) - the exception should be raised.

CodePudding user response:

because you are not returning anything when i is more than length, it would not continue

try this

l = "[1,[2,3],[4,5,6],[7,[8,90],10],[11,120,[13]]]"

def convert(l,out=[],i=0):
     while i<len(l) and l[i] != "]":
          if l[i] =="[":
              if i<len(l): 
               out_to_add,index = convert(l[i 1:],[])
               out.append(out_to_add)
               i =index 2
          elif l[i]!=",":
            out.append(l[i])
          i =1
     return out,i
print(convert(l)[0][0])
  • Related