Beste manier om interpunctie van een string te verwijderen

Het lijkt erop dat er een eenvoudigere manier moet zijn dan:

import string
s = "string. With. Punctuation?" # Sample string 
out = s.translate(string.maketrans("",""), string.punctuation)

Is dat zo?

Oplossing

Vanuit een efficiëntie perspectief, zul je niet winnen van

s.translate(None, string.punctuation)

Voor hogere versies van Python gebruik de volgende code:

s.translate(str.maketrans('', '', string.punctuation))

Het is het uitvoeren van onbewerkte string operaties in C met een lookup tabel - er is niet veel dat dat zal verslaan, maar het schrijven van je eigen C-code.

Als snelheid geen zorg is, is een andere optie dat wel:

exclude = set(string.punctuation)
s = ''.join(ch for ch in s if ch not in exclude)

Dit is sneller dan s.replace met elke char, maar zal'niet zo goed presteren als niet-zuivere python benaderingen zoals regexes of string.translate, zoals je kunt zien aan de onderstaande timings. Voor dit soort problemen loont het om het op een zo laag mogelijk niveau te doen.

Timing code:

import re, string, timeit

s = "string. With. Punctuation"
exclude = set(string.punctuation)
table = string.maketrans("","")
regex = re.compile('[%s]' % re.escape(string.punctuation))

def test_set(s):
    return ''.join(ch for ch in s if ch not in exclude)

def test_re(s):  # From Vinko's solution, with fix.
    return regex.sub('', s)

def test_trans(s):
    return s.translate(table, string.punctuation)

def test_repl(s):  # From S.Lott's solution
    for c in string.punctuation:
        s=s.replace(c,"")
    return s

print "sets      :",timeit.Timer('f(s)', 'from __main__ import s,test_set as f').timeit(1000000)
print "regex     :",timeit.Timer('f(s)', 'from __main__ import s,test_re as f').timeit(1000000)
print "translate :",timeit.Timer('f(s)', 'from __main__ import s,test_trans as f').timeit(1000000)
print "replace   :",timeit.Timer('f(s)', 'from __main__ import s,test_repl as f').timeit(1000000)

Dit geeft de volgende resultaten:

sets      : 19.8566138744
regex     : 6.86155414581
translate : 2.12455511093
replace   : 28.4436721802
Commentaren (11)

Ik gebruik meestal zoiets als dit:

>>> s = "string. With. Punctuation?" # Sample string
>>> import string
>>> for c in string.punctuation:
...     s= s.replace(c,"")
...
>>> s
'string With Punctuation'
Commentaren (2)

Niet per se eenvoudiger, maar een andere manier, als je meer bekend bent met de re familie.

import re, string
s = "string. With. Punctuation?" # Sample string 
out = re.sub('[%s]' % re.escape(string.punctuation), '', s)
Commentaren (3)