Удалить символы кроме цифр от строки с помощью Python?

Как я могу удалить все символы кроме чисел от строки?

123
задан jww 30 June 2019 в 13:11
поделиться

7 ответов

В Python 2. *, безусловно, самым быстрым подходом является метод .translate :

>>> x='aaa12333bb445bb54b5b52'
>>> import string
>>> all=string.maketrans('','')
>>> nodigs=all.translate(all, string.digits)
>>> x.translate(all, nodigs)
'1233344554552'
>>> 

string.maketrans создает таблицу перевода (строка length 256), который в данном случае совпадает с ''. join (chr (x) для x в диапазоне (256)) (просто быстрее сделать ;-). .translate применяет таблицу перевода (которая здесь не имеет значения, поскольку all по существу означает идентичность) И удаляет символы, присутствующие во втором аргументе - ключевой части.

.translate ] работает совсем иначе со строками Unicode (и строками в Python 3 - я делаю желаю, чтобы вопросы указывали, какая основная версия 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

... что показывает, что преимущество в производительности исчезает для такого рода задач "удаления" и становится снижением производительности.

так что метод 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

... что показывает, что преимущество в производительности исчезает для такого рода задач "удаления" и становится снижением производительности.

так что метод 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

... что показывает, что преимущество в производительности исчезает для такого рода задач «удаления» и становится снижением производительности.

Другой популярный подход не-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

... что показывает, что преимущество в производительности исчезает для такого рода задач "удаления" и становится снижением производительности.

Другой популярный подход не-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

... что показывает, что преимущество в производительности исчезает для такого рода задач "удаления" и становится снижением производительности.

В 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

... что показывает, что преимущество в производительности исчезает для такого рода задач «удаления» и становится снижением производительности.

В 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

... что показывает, что преимущество в производительности исчезает для такого рода задач «удаления» и становится снижением производительности.

несколько символов:

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

... что показывает, что преимущество в производительности исчезает для такого рода задач "удаления" и становится снижением производительности.

несколько символов:

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

... что показывает, что преимущество в производительности исчезает для такого рода задач "удаления" и становится снижением производительности.

108
ответ дан 24 November 2019 в 01:09
поделиться

Используйте выражение генератора:

>>> s = "foo200bar"
>>> new_s = "".join(i for i in s if i in "0123456789")
2
ответ дан 24 November 2019 в 01:09
поделиться

Уродливо, но работает:

>>> s
'aaa12333bb445bb54b5b52'
>>> a = ''.join(filter(lambda x : x.isdigit(), s))
>>> a
'1233344554552'
>>>
2
ответ дан 24 November 2019 в 01:09
поделиться

в соответствии со строками ответа Байера:

''.join(i for i in s if i.isdigit())
11
ответ дан 24 November 2019 в 01:09
поделиться

Вы можете использовать фильтр :

filter(lambda x: x.isdigit(), "dasdasd2313dsa")

На python3.0 вы должны присоединиться к этому (некрасиво :()

''.join(filter(lambda x: x.isdigit(), "dasdasd2313dsa"))
16
ответ дан 24 November 2019 в 01:09
поделиться
s=''.join(i for i in s if i.isdigit())

Другой вариант генератора.

58
ответ дан 24 November 2019 в 01:09
поделиться

Используйте re.sub , примерно так:

>>> import re
>>> re.sub("\D", "", "aas30dsa20")
'3020'

\ D соответствует любому нецифровому символу, поэтому приведенный выше код по существу заменяет каждый нецифровой символ для пустой строки.

Или вы можете использовать фильтр , вот так (в Python 2k):

>>> filter(lambda x: x.isdigit(), "aas30dsa20")
'3020'

Поскольку в Python 3k, фильтр возвращает итератор вместо списка , вместо этого можно использовать следующее:

>>> ''.join(filter(lambda x: x.isdigit(), "aas30dsa20"))
'3020'
173
ответ дан 24 November 2019 в 01:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: