Reputation: 33
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
Upvotes: 3
Views: 294
Reputation: 71451
Shorter no-import solution:
l = "[1,[2,3],[4,5,6],[7,[8,90],10],[11,120,[13]]]"
def to_list(d):
while d and (n:=d.pop(0)) != ']':
if n == '[':
yield list(to_list(d))
elif n.isdigit():
yield int(n+(x:=lambda :'' if not d[0].isdigit() else d.pop(0)+x())())
print(next(to_list(list(l))))
Output:
[1, [2, 3], [4, 5, 6], [7, [8, 90], 10], [11, 120, [13]]]
Upvotes: 2
Reputation: 3379
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.
Upvotes: 0
Reputation: 565
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])
Upvotes: 1
Reputation: 260790
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]]]
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]
Upvotes: 1