ignorar - python replace ñ
Pele todos los caracteres no numéricos(excepto ".") De una cadena en Python (6)
Aquí hay un código de muestra:
$ cat a.py
a = ''27893jkasnf8u2qrtq2ntkjh8934yt8.298222rwagasjkijw''
for i in xrange(1000000):
''''.join([c for c in a if c in ''1234567890.''])
$ cat b.py
import re
non_decimal = re.compile(r''[^/d.]+'')
a = ''27893jkasnf8u2qrtq2ntkjh8934yt8.298222rwagasjkijw''
for i in xrange(1000000):
non_decimal.sub('''', a)
$ cat c.py
a = ''27893jkasnf8u2qrtq2ntkjh8934yt8.298222rwagasjkijw''
for i in xrange(1000000):
''''.join([c for c in a if c.isdigit() or c == ''.''])
$ cat d.py
a = ''27893jkasnf8u2qrtq2ntkjh8934yt8.298222rwagasjkijw''
for i in xrange(1000000):
b = []
for c in a:
if c.isdigit() or c == ''.'': continue
b.append(c)
''''.join(b)
Y los resultados de tiempo:
$ time python a.py
real 0m24.735s
user 0m21.049s
sys 0m0.456s
$ time python b.py
real 0m10.775s
user 0m9.817s
sys 0m0.236s
$ time python c.py
real 0m38.255s
user 0m32.718s
sys 0m0.724s
$ time python d.py
real 0m46.040s
user 0m41.515s
sys 0m0.832s
Parece que la expresión regular es la ganadora hasta ahora.
Personalmente, considero que la expresión regular es tan legible como la comprensión de la lista. Si lo haces solo unas pocas veces, es probable que tengas un mayor impacto en la compilación de la expresión regular. Haz lo que acerta con tu código y estilo de codificación.
Tengo un muy buen snippit de código de trabajo, pero me preguntaba si alguien tiene mejores sugerencias sobre cómo hacer esto:
val = ''''.join([c for c in val if c in ''1234567890.''])
¿Qué harías?
Otro enfoque "pitónico"
filter( lambda x: x in ''0123456789.'', s )
pero la expresión regular es más rápida.
Puede usar una expresión regular (usando el módulo re
) para lograr lo mismo. El siguiente ejemplo coincide con las ejecuciones de [^/d.]
(Cualquier carácter que no sea un dígito decimal o un punto) y los reemplaza con la cadena vacía. Tenga en cuenta que si el patrón se compila con el indicador UNICODE
, la cadena resultante aún podría incluir números que no sean ASCII . Además, el resultado después de eliminar los caracteres "no numéricos" no es necesariamente un número válido.
>>> import re
>>> non_decimal = re.compile(r''[^/d.]+'')
>>> non_decimal.sub('''', ''12.34fe4e'')
''12.344''
Si el conjunto de caracteres fuera más grande, el uso de conjuntos como a continuación podría ser más rápido. Tal como es, esto es un poco más lento que a.py.
dec = set(''1234567890.'')
a = ''27893jkasnf8u2qrtq2ntkjh8934yt8.298222rwagasjkijw''
for i in xrange(1000000):
''''.join(ch for ch in a if ch in dec)
Al menos en mi sistema, puede ahorrar un poco de tiempo (y memoria si su cadena fue lo suficientemente larga como para importar) mediante el uso de una expresión de generador en lugar de una comprensión de lista en a.py:
a = ''27893jkasnf8u2qrtq2ntkjh8934yt8.298222rwagasjkijw''
for i in xrange(1000000):
''''.join(c for c in a if c in ''1234567890.'')
Ah, y esta es la forma más rápida que he encontrado hasta ahora en esta cadena de prueba (mucho más rápido que la expresión regular) si estás haciendo esto muchas, muchas veces y estás dispuesto a soportar la sobrecarga de construir un par de tablas de caracteres.
chrs = ''''.join(chr(i) for i in xrange(256))
deletable = ''''.join(ch for ch in chrs if ch not in ''1234567890.'')
a = ''27893jkasnf8u2qrtq2ntkjh8934yt8.298222rwagasjkijw''
for i in xrange(1000000):
a.translate(chrs, deletable)
En mi sistema, eso se ejecuta en ~ 1.0 segundos donde la expresión regular b.py se ejecuta en ~ 4.3 segundos.
Una solución simple es usar expesiones regulares
import re
re.sub("[^0-9^.]", "", data)
import string
filter(lambda c: c in string.digits + ''.'', s)