0

I have a string

string = "[abc, 2, '5', [1abc, 1bcd], func_name(arg1,arg2)]"

I need to convert it into a list as below

list1 = ['abc', 2, '5', ['1abc', '1bcd'], 'func_name(arg1,arg2)']

First, I tried the string.split(',') method, (Didn't work)

def string_to_list(value: str, sep=','):
    # Remove spaces from both sides : strip(' ')
    # then remove '[' from left : lstrip('['])
    # then remove ']' from right : rstrip('[')
    value = value.strip(' ')
    if value.startswith('[') and value.endswith(']'):
        value = value[1:][:-1]
    value_s = value.split(',')
    return value_s

Output : ['abc', ' 2', " '5'", ' [1abc', ' 1bcd]', ' func_name(arg1', 'arg2)']

After that I tried json.loads() method which also didn't work and raised error.

File "...\Python\lib\json\decoder.py", line 355, in raw_decode raise JSONDecodeError("Expecting value", s, err.value) from None

JSONDecodeError: Expecting value

ast.literal_eval() also raised error:

  File "< unknown >", line 1
    [abc, 2, '5', [1abc, 1bcd], func_name(arg1,arg2)]
                    ^
SyntaxError: invalid syntax

After that I tried:

def get_best_dtype(value: str):
    """Selects the best from: None,bool,int,float,str"""
    if value in ("None", ''):
        return None
    if value.lower() in ('true', 'false'):
        final_value = bool(value.lower() == "true")
        return final_value
    try:
        final_value = int(value)
    except ValueError:
        try:
            final_value = float(value)
        except ValueError:
            final_value = value
    return final_value


def split_string(string: str, sep: str = ','):
    """It's getting more & more complicated with every new thing being tracked."""
    if string == '':
        return ['']
    string += ','
    length = len(string)
    i = 0
    temp_str = ''
    final = []
    inside_brackets = 0
    inside_comma = False
    inside_commas = False
    inside_any = False

    while i != length:
        char = string[i]
        if char != sep or inside_any:
            temp_str += char
        if char == '[' and not (inside_comma or inside_commas):
            inside_brackets += 1
        elif char == ']' and not (inside_comma or inside_commas):
            inside_brackets -= 1
            if inside_brackets == 0:
                if '[]' not in temp_str:
                    temp_str = string_to_list(temp_str, sep)

            if inside_brackets < 0:
                inside_brackets = 0
        elif char == '"' and not (inside_brackets or inside_comma):
            inside_commas = not inside_commas
        elif char == "'" and not (inside_brackets or inside_commas):
            inside_comma = not inside_comma

        inside_any = (inside_brackets or inside_comma or inside_commas)
        if ((not inside_any) and char == sep):
            if not isinstance(temp_str, list):
                temp_str = get_best_dtype(temp_str)
            final.append(temp_str)
            temp_str = ''

        i += 1
    return final


def string_to_list(value: str, sep=','):
    # Remove spaces from both sides : strip(' ')
    # then remove '[' from left : lstrip('['])
    # then remove ']' from right : rstrip('[')
    value = value.strip(' ')
    if value.startswith('[') and value.endswith(']'):
        value = value[1:][:-1]
    value_s = split_string(value, sep)
    return value_s

Output: ['abc', 2, " '5'", ['1abc', ' 1bcd'], ' func_name(arg1', 'arg2)']

Expected output : ['abc', 2, '5', ['1abc', '1bcd'], 'func_name(arg1,arg2)']

'func_name(arg1,arg2)' got split into two parts [' func_name(arg1', 'arg2)']

But before making it more complicated I wanted to ask

  • If there is any easier way to do this?
  • Is this the right way to do it?

Any help would be greatly appreciated.

Thanks ☺️ Have a great day.

M S
  • 1
  • 3
  • 2
    Does this answer your question? [How to convert string representation of list to a list?](https://stackoverflow.com/questions/1894269/how-to-convert-string-representation-of-list-to-a-list) – gajendragarg Mar 01 '22 at 10:43
  • 1
    Where do you get that list from? May be easier to fix upstream. – timgeb Mar 01 '22 at 10:44
  • The string is taken as input – M S Mar 01 '22 at 10:47
  • 1
    This is hopeless. Don't take that string from input. If you allow arbitrary inputs/nesting you'll find to write a parser. Which looks like you started doing. Have fun testing it ... – timgeb Mar 01 '22 at 10:50

0 Answers0