No Python loops. No recursion. No regexes.
Just computing the difference between the cumulative counts of '('
and ')'
:
import numpy as nps = '()a(x(x)x)b(x)c()d()'s_array = np.array(list(s))mask_open = s_array=='('mask_close = s_array==')'# Compute in how many parentheses each character is nested,# while considering ')' as not nested:nestedness_except_close = np.cumsum(mask_open) - np.cumsum(mask_close)# ... and while considering ')' as nested:nestedness = nestedness_except_close + mask_close# Select only characters that aren't in any parenthesesresult = ''.join(s_array[nestedness < 1])
This might be faster than other solutions.
Optional validity checks for the string:
# Check whether the number of `'('`s and `')'`s is the sameassert(nestedness_except_close[-1] == 0)# Check whether some parentheses get closed before they got openedassert((nestedness_except_close >= 0).all())
If you don't want to use NumPy, you can use itertools.accumulate()
to compute the cumulative sums.