David David - 10 days ago 5
Python Question

Series of conditionals in function not working properly

I have a really simple program to remove the first level of brackets in a string, but it seems not be working. There seems to be a problem with my logic but I can't spot it.

Given a string like

AB(CCDC)((EF)G)H
, I ought to return
ABCCDC(EF)GH
. But for some reason my program returns
ABCCDC((EF))GH
. Here is the program:

def removeBrackets(string):
level = 0
list1 = list(string)
poses = []
for i in range(len(list1)):
print level, list1[i]
if level == 0 and list1[i] == '(':
print "skipping!"
level += 1
continue
elif level > 0 and list1[i] == '(':
poses.append(list1[i])
level += 1
elif level == 1 and list1[i] == ')':
print "skipping!"
level -= 1
continue
elif level > 0 and list1[i] == ')':
poses.append(list1[i])
level -= 1
print "adding " + list1[i] + "!"
poses.append(list1[i])
result = ""
for i in poses:
result += i
return result


As far as printing out
skipping!
and
adding!
, it performs as expected. but it still adds two brackets that it shouldn't. Please help.

Answer
    elif level > 0 and list1[i] == '(':
        poses.append(list1[i])
        level += 1

    ...

    elif level > 0 and list1[i] == ')':
        poses.append(list1[i])
        level -= 1

    ...

    print "adding " + list1[i] + "!"
    poses.append(list1[i])

The first two appends are redundant given the last one. They cause duplicate sets of parentheses to be added.

For what it's worth, you could simplify your function a bit.

  1. list1 isn't needed. You can work with a string the same way you'd work with a list.

  2. Instead of enumerating over the indices of string, you could iterate over string directly with for ch in string. That gets rid of the numerous list1[i] lookups. (If you really do want to know the index of each character, try for i, ch in enumerate(string).

  3. Some redundancy is removed if you split up the character checks from the level ones. If you see a parenthesis you modify level either way, so best to write level += 1 and level -= 1 just once.

  4. poses is an odd name for a variable. How about parts?

  5. The last loop to create a string result can be replaced with ''.join(parts). This is a funny-looking, but common, Python idiom.

Result:

def removeBrackets(string):
    level = 0
    parts = []

    for ch in string:
        print level, ch

        if ch == '(':
            level += 1

            if level == 1:
                print "skipping!"
                continue
        elif ch == ')':
            level -= 1

            if level == 0:
                print "skipping!"
                continue

        print "adding " + ch + "!"
        parts.append(ch)

    return ''.join(parts)