https://leetcode.com/problems/mini-parser/ 


def iol_parser(string, start, brackets):
    if string[start] == '[':
        eol = brackets[start]
        return listarg_parser(string, start + 1, eol - 1, brackets), eol + 1
    else:
        # print(string[start:])
        idx = start
        while idx < len(string) and string[idx] != ',' and string[idx] != ']':
            idx += 1

        return int(string[start : idx]), idx

def listarg_parser(string, start, end, brackets):
    arg, argend = iol_parser(string, start, brackets)
    args = [arg]
    # print(arg)
    while argend < end:
        arg, argend = iol_parser(string, argend + 1, brackets)
        args.append(arg)
    return args

class Solution:
    def deserialize(self, s: str) -> NestedInteger:
        stack = []
        brackets = {}
        for i, e in enumerate(s):
            if e == '[':
                stack.append(i)
            elif e == ']':
                brackets[stack.pop()] = i
        ret = iol_parser(s, 0, brackets)[0]
        #print(ret)
        return NestedInteger(ret)
                

versus 

class Solution:
    def deserialize(self, s):
        stack, num, last = [], "", None
        for c in s:
            if c.isdigit() or c == "-": num += c
            elif c == "," and num:
                stack[-1].add(NestedInteger(int(num)))
                num = ""
            elif c == "[":
                elem = NestedInteger()
                if stack: stack[-1].add(elem)
                stack.append(elem)
            elif c == "]":
                if num:
                    stack[-1].add(NestedInteger(int(num)))
                    num = ""
                last = stack.pop()
        return last if last else NestedInteger(int(num))

Another example is in this problem, Given an encoded string in form of "ab[cd]{2}def" return decoded string "abcdcddef". The recursive solution is as follows

from collections import deque

def parse(s, start, end, brackets):
    idx = start
    builder = []
    while idx < end:
        c = s[idx]
        if c == '[':
            int_start = brackets[idx] + 2
            int_len = s[int_start:].index('}')
            integer = int(s[int_start : int_start + int_len])
            builder.append(
                parse(s, idx + 1, brackets[idx], brackets) * integer
            )
            idx = brackets[idx] + 2 + int_len + 1
        else:
            builder.append(c)
            idx += 1
    return ''.join(builder)

def decodeString2(s: str) -> str:
        brackets = {}
        stack = []
        for i, c in enumerate(s):
            if c == '[':
                stack.append(i)
            if c == ']':
                brackets[stack.pop()] = i
        return parse(s, 0, len(s), brackets)

The stack based solution is a lot shorter, even though it's a little bit harder to come up with --

def decodeString(s):
    stk = []
    cur = ""
    num = 0
    for ch in s:
        if ch.isdigit():
            num = num*10 + int(ch)
        elif ch.isalpha():
            cur += ch
        elif ch == "(":
            stk.append(cur)
            cur = ""
        elif ch == "}":
            pre = stk.pop()
            cur = pre + cur*num
            num = 0

    while stk:
        cur = stk.pop() + cur
    return cur