93

I want to remove any brackets from a string. Why doesn't this work properly?

>>> name = "Barack (of Washington)"
>>> name = name.strip("(){}<>")
>>> print name
Barack (of Washington
Tim Pietzcker
  • 328,213
  • 58
  • 503
  • 561
AP257
  • 89,519
  • 86
  • 202
  • 261

7 Answers7

121

Because that's not what strip() does. It removes leading and trailing characters that are present in the argument, but not those characters in the middle of the string.

You could do:

name= name.replace('(', '').replace(')', '').replace ...

or:

name= ''.join(c for c in name if c not in '(){}<>')

or maybe use a regex:

import re
name= re.sub('[(){}<>]', '', name)
bobince
  • 528,062
  • 107
  • 651
  • 834
78

I did a time test here, using each method 100000 times in a loop. The results surprised me. (The results still surprise me after editing them in response to valid criticism in the comments.)

Here's the script:

import timeit

bad_chars = '(){}<>'

setup = """import re
import string
s = 'Barack (of Washington)'
bad_chars = '(){}<>'
rgx = re.compile('[%s]' % bad_chars)"""

timer = timeit.Timer('o = "".join(c for c in s if c not in bad_chars)', setup=setup)
print "List comprehension: ",  timer.timeit(100000)


timer = timeit.Timer("o= rgx.sub('', s)", setup=setup)
print "Regular expression: ", timer.timeit(100000)

timer = timeit.Timer('for c in bad_chars: s = s.replace(c, "")', setup=setup)
print "Replace in loop: ", timer.timeit(100000)

timer = timeit.Timer('s.translate(string.maketrans("", "", ), bad_chars)', setup=setup)
print "string.translate: ", timer.timeit(100000)

Here are the results:

List comprehension:  0.631745100021
Regular expression:  0.155561923981
Replace in loop:  0.235936164856
string.translate:  0.0965719223022

Results on other runs follow a similar pattern. If speed is not the primary concern, however, I still think string.translate is not the most readable; the other three are more obvious, though slower to varying degrees.

JasonFruit
  • 7,764
  • 5
  • 46
  • 61
  • 2
    thanks for this - educative question, not only did I learn that strip() doesn't do what I thought, I also learned three other ways to achieve what I wanted, and which was the fastest! – AP257 Oct 11 '10 at 15:53
  • 1
    wont work for unicode: translate() only takes one argument (table) with unicode. – Rich Tier Jul 16 '13 at 18:32
  • 17
    minus 1: For making something about speed which should be about code clarity and robustness. – jwg Jan 05 '16 at 10:52
  • @jwg , you're totally right; looking back at this, it's an exercise in high-visibility missing of the point. Somehow, though, it keeps getting upvotes. (I did learn some interesting things about using timeit, though.) – JasonFruit Aug 21 '17 at 11:57
17

string.translate with table=None works fine.

>>> name = "Barack (of Washington)"
>>> name = name.translate(None, "(){}<>")
>>> print name
Barack of Washington
cherish
  • 1,370
  • 1
  • 11
  • 16
16

Because strip() only strips trailing and leading characters, based on what you provided. I suggest:

>>> import re
>>> name = "Barack (of Washington)"
>>> name = re.sub('[\(\)\{\}<>]', '', name)
>>> print(name)
Barack of Washington
Ruel
  • 15,438
  • 7
  • 38
  • 49
10

strip only strips characters from the very front and back of the string.

To delete a list of characters, you could use the string's translate method:

import string
name = "Barack (of Washington)"
table = string.maketrans( '', '', )
print name.translate(table,"(){}<>")
# Barack of Washington
unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
0

Since strip only removes characters from start and end, one idea could be to break the string into list of words, then remove chars, and then join:

s = 'Barack (of Washington)'
x = [j.strip('(){}<>') for j in s.split()]
ans = ' '.join(j for j in x)
print(ans)
Litz
  • 1
  • 1
-4

For example string s="(U+007c)"

To remove only the parentheses from s, try the below one:

import re
a=re.sub("\\(","",s)
b=re.sub("\\)","",a)
print(b)
alexander.polomodov
  • 5,396
  • 14
  • 39
  • 46
Siva Kumar
  • 459
  • 4
  • 6