@JG: Tengo gtk.Entry () y quiero que se ingrese flotante múltiple.
Jan Tojnar
1
@JanTojnar utiliza el método re.sub según la respuesta dos y enumera explícitamente qué caracteres mantener, por ejemplo, re.sub ("[^ 0123456789 \.]", "", "Poo123.4and5fish")
Roger Heathcote
Respuestas:
112
En Python 2. *, con mucho, el enfoque más rápido es el .translatemétodo:
string.maketranscrea una tabla de traducción (una cadena de longitud 256) que en este caso es la misma que ''.join(chr(x) for x in range(256))(simplemente más rápida de hacer ;-). .translateaplica la tabla de traducción (que aquí es irrelevante ya queall esencialmente significa identidad) Y elimina los caracteres presentes en el segundo argumento, la parte clave.
.translatefunciona de manera muy diferente en cadenas Unicode (y cadenas en Python 3 - lo hago preguntas deseos especifican los cuales importante de liberación de Python es de interés!) - no es este sencillo, no es tan rápido, aunque todavía bastante usable.
Volviendo a 2. *, la diferencia de rendimiento es impresionante ...:
$ 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
Acelerar las cosas entre 7 y 8 veces no es nada fácil, por lo translateque vale la pena conocer y utilizar el método. El otro enfoque popular no 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
es 50% más lento que RE, por lo que el .translateenfoque lo supera en un orden de magnitud.
En Python 3, o para Unicode, debe pasar .translateuna asignación (con ordinales, no caracteres directamente, como teclas) que devuelve Nonelo que desea eliminar. Aquí hay una manera conveniente de expresar esto para eliminar "todo menos" algunos caracteres:
import string
classDel: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)
También emite '1233344554552'. Sin embargo, poniendo esto en xx.py tenemos ...:
$ 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
... que muestra que la ventaja de rendimiento desaparece, para este tipo de tareas de "eliminación", y se convierte en una disminución del rendimiento.
@sunqiang, sí, absolutamente, hay una razón por la que Py3k ha ido a Unicode como EL tipo de cadena de texto, en lugar de cadenas de bytes como en Py2, la misma razón por la que Java y C # siempre han tenido el mismo meme "cadena significa unicode" ... algunos gastos generales, tal vez, ¡pero MUCHO mejor soporte para casi cualquier cosa menos inglés! -).
Alex Martelli
29
x.translate(None, string.digits)en realidad da como resultado 'aaabbbbbb', que es lo contrario de lo que se pretende.
Tom Dalling
44
Haciendo eco de los comentarios de Tom Dalling, su primer ejemplo conserva todos los caracteres indeseables: hace lo contrario de lo que dijo.
Chris Johnson
3
@ RyanB.Lynch et al, la falla fue con un editor posterior y otros dos usuarios que aprobaron dicha edición , lo que, de hecho, es totalmente incorrecto. Revertido
Nick T
1
anulando la allconstrucción ... no estoy seguro de eso!
Andy Hayden
197
Uso re.sub, así:
>>>import re
>>> re.sub('\D','','aas30dsa20')'3020'
\D coincide con cualquier carácter que no sea un dígito, por lo tanto, el código anterior reemplaza esencialmente cada carácter que no sea un dígito para la cadena vacía.
O puede usar filter, así (en Python 2):
>>> filter(str.isdigit,'aas30dsa20')'3020'
Dado que en Python 3, filterdevuelve un iterador en lugar de a list, puede usar lo siguiente en su lugar:
Es malo en una tarea tan simple, la segunda es la mejor, creo, porque los métodos 'es ...' son los más rápidos para las cadenas.
f0b0s
su ejemplo de filtro está limitado a py2k
SilentGhost
2
@ f0b0s-iu9-info: ¿lo cronometraste? en mi máquina (py3k) RE es el doble de rápido que el filtro con isdigit, generador con isdigtestá a medio camino entre ellos
SilentGhost
@SilentGhost: Gracias, estaba usando IDLE de py2k. Ya está arreglado.
João Silva
1
@asmaier Simplemente use rpara cadena cruda:re.sub(r"\D+", "", "aas30dsa20")
Obtengo un TypeError: translate () toma exactamente un argumento (2 dados). Por qué esta pregunta fue votada en su estado actual es bastante frustrante.
Bobort
la traducción cambió de python 2 a 3. La sintaxis que usa este método en python 3 es x.translate (str.maketrans ('', '', string.digits)) y x.translate (str.maketrans ('', '' , string.ascii_letters)). Ninguna de estas tiras de espacio en blanco. Realmente ya no recomendaría este enfoque ...
ZaxR
5
La opción menciona en los comentarios que quiere mantener el lugar decimal. Esto se puede hacer con el método re.sub (según el segundo y la mejor respuesta de la OMI) enumerando explícitamente los caracteres para mantener, por ejemplo
En mi código verifico el número de períodos en la cadena de entrada y provoco un error si es más de 1.
Roger Heathcote
4
Una versión rápida para Python 3:
# xx3.pyfrom collections import defaultdict
import string
_NoneType= type(None)def keeper(keep):
table = defaultdict(_NoneType)
table.update({ord(c): c for c in keep})return table
digit_keeper = keeper(string.digits)
Aquí hay una comparación de rendimiento vs. regex:
$ python3.3-mtimeit -s'import xx3; x="aaa12333bb445bb54b5b52"''x.translate(xx3.digit_keeper)'1000000 loops, best of 3:1.02 usec per loop
$ python3.3-mtimeit -s'import re; r = re.compile(r"\D"); x="aaa12333bb445bb54b5b52"''r.sub("", x)'100000 loops, best of 3:3.43 usec per loop
Entonces, es un poco más de 3 veces más rápido que la expresión regular, para mí. También es más rápido que el class Delanterior, porque defaultdictrealiza todas sus búsquedas en C, en lugar de Python (lento). Aquí está esa versión en mi mismo sistema, para comparar.
$ python3.3-mtimeit -s'import xx; x="aaa12333bb445bb54b5b52"''x.translate(xx.DD)'100000 loops, best of 3:13.6 usec per loop
@SilentGhost es mi malentendido. lo había corregido gracias :)
Gant
En realidad, con este método, no creo que necesite usar "unirse". filter(lambda x: x.isdigit(), s)funcionó bien para mí ... oh, es porque estoy usando Python 2.7.
Respuestas:
En Python 2. *, con mucho, el enfoque más rápido es el
.translate
método:string.maketrans
crea una tabla de traducción (una cadena de longitud 256) que en este caso es la misma que''.join(chr(x) for x in range(256))
(simplemente más rápida de hacer ;-)..translate
aplica la tabla de traducción (que aquí es irrelevante ya queall
esencialmente significa identidad) Y elimina los caracteres presentes en el segundo argumento, la parte clave..translate
funciona de manera muy diferente en cadenas Unicode (y cadenas en Python 3 - lo hago preguntas deseos especifican los cuales importante de liberación de Python es de interés!) - no es este sencillo, no es tan rápido, aunque todavía bastante usable.Volviendo a 2. *, la diferencia de rendimiento es impresionante ...:
Acelerar las cosas entre 7 y 8 veces no es nada fácil, por lo
translate
que vale la pena conocer y utilizar el método. El otro enfoque popular no RE ...:es 50% más lento que RE, por lo que el
.translate
enfoque lo supera en un orden de magnitud.En Python 3, o para Unicode, debe pasar
.translate
una asignación (con ordinales, no caracteres directamente, como teclas) que devuelveNone
lo que desea eliminar. Aquí hay una manera conveniente de expresar esto para eliminar "todo menos" algunos caracteres:También emite
'1233344554552'
. Sin embargo, poniendo esto en xx.py tenemos ...:... que muestra que la ventaja de rendimiento desaparece, para este tipo de tareas de "eliminación", y se convierte en una disminución del rendimiento.
fuente
x.translate(None, string.digits)
en realidad da como resultado'aaabbbbbb'
, que es lo contrario de lo que se pretende.all
construcción ... no estoy seguro de eso!Uso
re.sub
, así:\D
coincide con cualquier carácter que no sea un dígito, por lo tanto, el código anterior reemplaza esencialmente cada carácter que no sea un dígito para la cadena vacía.O puede usar
filter
, así (en Python 2):Dado que en Python 3,
filter
devuelve un iterador en lugar de alist
, puede usar lo siguiente en su lugar:fuente
isdigit
, generador conisdigt
está a medio camino entre ellosr
para cadena cruda:re.sub(r"\D+", "", "aas30dsa20")
Otra variante de generador.
fuente
Puedes usar filter:
En python3.0 tienes que unirte a esto (un poco feo :()
fuente
str
paralist
asegurarse de que funciona tanto en py2 como en py3:''.join(filter(lambda x: x.isdigit(), list("dasdasd2313dsa")))
en la línea de la respuesta de bayer:
fuente
-
no es un dígito.Puedes hacerlo fácilmente usando Regex
fuente
eliminará todos los dígitos de la cadena. Para eliminar letras y conservar los dígitos, haga esto:
fuente
TypeError
: translate () toma exactamente un argumento (2 dados). Por qué esta pregunta fue votada en su estado actual es bastante frustrante.La opción menciona en los comentarios que quiere mantener el lugar decimal. Esto se puede hacer con el método re.sub (según el segundo y la mejor respuesta de la OMI) enumerando explícitamente los caracteres para mantener, por ejemplo
fuente
Una versión rápida para Python 3:
Aquí hay una comparación de rendimiento vs. regex:
Entonces, es un poco más de 3 veces más rápido que la expresión regular, para mí. También es más rápido que el
class Del
anterior, porquedefaultdict
realiza todas sus búsquedas en C, en lugar de Python (lento). Aquí está esa versión en mi mismo sistema, para comparar.fuente
Use una expresión generadora:
fuente
''.join(n for n in foo if n.isdigit())
Feo pero funciona:
fuente
list(s)
?filter(lambda x: x.isdigit(), s)
funcionó bien para mí ... oh, es porque estoy usando Python 2.7.Había observado que join es más rápido que sub.
fuente
Puedes leer cada personaje. Si es un dígito, inclúyalo en la respuesta. El
str.isdigit()
método es una forma de saber si un personaje es un dígito.fuente
No es un trazador de líneas pero muy simple:
fuente
Yo usé esto
'letters'
debe contener todas las letras de las que desea deshacerse:Output = Input.translate({ord(i): None for i in 'letters'}))
Ejemplo:
Input = "I would like 20 dollars for that suit" Output = Input.translate({ord(i): None for i in 'abcdefghijklmnopqrstuvwxzy'})) print(Output)
Salida:
20
fuente