Переменная caps перегружена: изначально она означает строку, содержащую скобки, а затем словарь. Из-за этого filter при выполнении в строке "for cap in source:" проверяет, есть ли символ среди ключей словаря, а не в исходной строке, а закрывающей скобки там нет. Назовите словарь по-другому, и всё заработает:
def is_balanced(source, caps):
source = filter(lambda x: x in caps, source)
caps_dict = dict(zip(caps[::2], caps[1::2]))
stack = []
for cap in source:
if stack and cap == caps_dict.get(stack[-1], ""):
stack.pop()
else:
stack.append(cap)
return not stack