简体   繁体   中英

How to recursively remove the first set of parantheses in string of nested parantheses? (in Python)

EDIT: Say I have a string of nested parentheses as follows: ((AB)CD(E(FG)HI((J(K))L))) (assume the parantheses are balanced and enclose dproperly How do i recursively remove the first set of fully ENCLOSED parantheses of every subset of fully enclosed parentheses?

So in this case would be (ABCD(E(FG)HI(JK)). (AB) would become AB because (AB) is the first set of closed parentheses in a set of closed parentheses (from (AB) to K)), E is also the first element of a set of parentheses but since it doesn't have parentheses nothing is changed, and (J) is the first element in the set ((J)K) and therefore the parentheses would be removed.

This is similar to building an expression tree and so far I have parsed it into a nested list and thought I can recursively check if the first element of every nested list isinstance(type(list)) but I don't know how?

The nested list is as follows:

arr = [['A', 'B'], 'C', 'D', ['E', ['F', 'G'], 'H', 'I', [['J'], 'K']]]

Perhaps convert it into:

arr = [A, B, C, D, [E, [F, G], H, I, [J, K]]

Is there a better way?

You need to reduce your logic to something clear enough to program. What I'm getting from your explanations would look like the code below. Note that I haven't dealt with edge cases: you'll need to check for None elements, hitting the end of the list, etc.

def simplfy(parse_list):

    # Find the first included list; 
    #   build a new list with that set of brackets removed.
    reduce_list = []
    for pos in len(parse_list):
        elem = parse_list[pos]
        if isinstance(elem, list):
            # remove brackets; construct new list
            reduce_list = parse_list[:pos]
            reduce_list.extend(elem)
            reduce_list.extend(parse_list[pos+1:]

    # Recur on each list element
    return_list = []
    for elem in parse_list
        if isinstance(elem, list):
            return_list.append(simplfy(elem))
        else:
            return_list.append(elem)

    return return_list

If I understood the question correctly, this ugly function should do the trick:

def rm_parens(s):
    s2 = []
    consec_parens = 0
    inside_nested = False
    for c in s:
        if c == ')' and inside_nested:
            inside_nested = False
            consec_parens = 0
            continue
        if c == '(':
            consec_parens += 1
        else:
            consec_parens = 0
        if consec_parens == 2:
            inside_nested = True
        else:
            s2.append(c)
    s2 = ''.join(s2)
    if s2 == s:
        return s2
    return rm_parens(s2)

s = '((AB)CD(E(FG)HI((J)K))'
s = rm_parens(s)
print(s)

Note that this function will call itself recursively until no consecutive parentheses exist. However, in your example, ((AB)CD(E(FG)HI((J)K)), a single call is enough to produce (ABCD(E(FG)HI(JK)).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM