В Python 2. * самый быстрый подход - это метод .translate
:
>>> x='aaa12333bb445bb54b5b52'
>>> import string
>>> all=string.maketrans('','')
>>> nodigs=all.translate(all, string.digits)
>>> x.translate(all, nodigs)
'1233344554552'
>>>
string.maketrans
создает таблицу перевода (строку длиной 256), которая в этом случае совпадает с ''.join(chr(x) for x in range(256))
(просто быстрее; ;). .translate
применяет таблицу перевода (которая здесь неактуальна, поскольку all
по существу означает идентичность) И удаляет символы, присутствующие во втором аргументе - ключевой части.
.translate
работает очень по-разному для строк Unicode (и строк в Python 3 - I do хотел бы задать вопросы, которые представляют интерес для основного выпуска Python!) - не так просто, не довольно быстро, хотя все еще вполне пригодно для использования.
Возвращаясь к 2. *, разница в производительности впечатляет ...:
$ python -mtimeit -s'import string; all=string.maketrans("", ""); nodig=all.translate(all, string.digits); x="aaa12333bb445bb54b5b52"' 'x.translate(all, nodig)'
1000000 loops, best of 3: 1.04 usec per loop
$ python -mtimeit -s'import re; x="aaa12333bb445bb54b5b52"' 're.sub(r"\D", "", x)'
100000 loops, best of 3: 7.9 usec per loop
Ускорение вещей в 7-8 раз - вряд ли арахис, поэтому метод translate
стоит того, чтобы его изучить и использовать. Другой популярный не-RE подход ...:
$ python -mtimeit -s'x="aaa12333bb445bb54b5b52"' '"".join(i for i in x if i.isdigit())'
100000 loops, best of 3: 11.5 usec per loop
на 50% медленнее, чем RE, поэтому подход .translate
превосходит его более чем на порядок.
В Python 3 или для Unicode вам нужно передать .translate
отображение (с порядковыми номерами, а не символами напрямую, как ключи), которое возвращает None
для того, что вы хотите удалить. Вот удобный способ выразить это для удаления «всего, кроме» нескольких символов:
import string
class Del:
def __init__(self, keep=string.digits):
self.comp = dict((ord(c),c) for c in keep)
def __getitem__(self, k):
return self.comp.get(k)
DD = Del()
x='aaa12333bb445bb54b5b52'
x.translate(DD)
также испускает '1233344554552'
. Однако, поместив это в xx.py, мы получим ...:
$ python3.1 -mtimeit -s'import re; x="aaa12333bb445bb54b5b52"' 're.sub(r"\D", "", x)'
100000 loops, best of 3: 8.43 usec per loop
$ python3.1 -mtimeit -s'import xx; x="aaa12333bb445bb54b5b52"' 'x.translate(xx.DD)'
10000 loops, best of 3: 24.3 usec per loop
... который показывает, что преимущество в производительности исчезает для такого рода задач «удаления» и становится снижением производительности.