How do you check whether the brackets in a string are balanced?
Use a stack. Push every opening bracket you see. When you meet a closing bracket, the stack must be non-empty and its top must be the matching opening bracket; if either fails the string is invalid. At the end the stack must be empty, because an unclosed opening bracket is also a failure.
def is_valid(text):
pairs = {")": "(", "]": "[", "}": "{"}
stack = []
for char in text:
if char in pairs.values():
stack.append(char)
elif char in pairs:
if not stack or stack.pop() != pairs[char]:
return False
return not stack
print(is_valid("()[]{}"))
print(is_valid("([)]"))
print(is_valid(""))The outputs are True, False and True. The second string has the right brackets in the wrong order: the closing parenthesis meets an open square bracket on top of the stack, so it fails immediately even though the counts balance.
The mechanism is that a stack enforces nesting. The most recent opening bracket is the only one that a closing bracket is allowed to close, which is exactly the nesting rule. Matching counts are not enough, and the example in the second print is the standard way to show that difference.
The trade-off to name is that you reject early, which is what you want in a real parser, but it means the function cannot tell you where the mismatch happened. If you want to report the offending position, you keep the index of each bracket on the stack rather than the bracket itself. The other detail is the empty string, which is valid by convention, and the code above returns True for it because the final check is that the stack is empty.