简体   繁体   中英

Find all parentheses in a string by pairs - Python 3

I'm trying to get a list of tuples with the indices of all sets of parentheses in a string. I can find the left and right parens independently easily with list comprehensions:

s = "12(34)567"

left_parens = [i for i,j in enumerate(s) if j == "("]
right_parens = left_parens = [i for i,j in enumerate(s) if j == ")"]

The most logical way to turn these separate lists into a list of tuples with (left paren, right paren) pairs is with the zip function.

parens = zip(right_parens,left_parens)
print(list(parens))

From this I would expect to yield:

[(2,5)]

But instead, I get:

[(5,5)]

Even if I switch the order like this:

parens = zip(left_parens,right_parens)

The result is still [(5,5)].

What am I missing?

Try it online!

The problem is here:

right_parens = left_parens = [ ... ]

You set the two lists to the same memory area; they are now the same list. Keep them separate:

left_parens  = [i for i,j in enumerate(s) if j == "("]
right_parens = [i for i,j in enumerate(s) if j == ")"]

EXTENSION

Note that your algorithm won't work for nested parentheses:

s = "1(2(34)56)7"

Output:

[(1, 6), (3, 9)]

You can solve this with a counter: pre-increment for each Lparen, post-decrement for each Rparen. Mark each paren location with its nesting level:

string 1(2(34)56)7(8)
marker -1-2--2--1-1-1

From here, move from the inside out: match the 2's, left to right (only one pair), then the 1's (two pairs). Coding is left as an exercise for the student. :-) From here, you can

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