A bit late to the game but was looking for an alternative/shorter way of finding matching parenthesis....came up with this:
def matching_parentheses(string, idx):
if idx < len(string) and string[idx] == "(":
opening = [i for i, c in enumerate(string[idx + 1 :]) if c == "("]
closing = [i for i, c in enumerate(string[idx + 1 :]) if c == ")"]
for i, j in enumerate(closing):
if i >= len(opening) or j < opening[i]:
return j + idx + 1
return -1
So you can do something like
result = {}
for i, j in enumerate(text):
if j=='(':
result[i] = matching_parentheses(text, i)
print(result)
Which produces
{4: 14, 7: 8, 9: 10}
Edit...here's an updated version which returns the dict directly:
def matching_parentheses(string):
opening = []
mydict = {}
# loop over the string
for i,c in enumerate(string):
# new ( found => push it to the stack
if c == '(':
opening.append(i)
# new ) found => pop and create an entry in the dict
elif c==')':
# we found a ) so there must be a ( on the stack
if not opening:
return False
else:
mydict[opening.pop()] = i
# return dict if stack is empty
return mydict if not opening else False
or a more condensed version could be
def matching_parentheses(string):
op= []
dc = {
op.pop() if op else -1:i for i,c in enumerate(string) if
(c=='(' and op.append(i) and False) or (c==')' and op)
}
return False if dc.get(-1) or op else dc
And now you can do
text = 'aaaa(bb()()ccc)dd'
m = matching_parentheses(text)
print(m)