Estoy tratando de eliminar caracteres específicos de una cadena usando Python. Este es el código que estoy usando ahora. Por desgracia, parece que no hace nada a la cadena.
for char in line:
if char in " ?.!/;:":
line.replace(char,'')
¿Cómo puedo hacer esto correctamente?
Las cadenas en Python son inmutables (no pueden ser cambiadas). Debido a esto, el efecto de line.replace(...)
es sólo crear una nueva cadena, en lugar de cambiar la anterior. Necesitas rebind (asignar) a linea
para que esa variable tome el nuevo valor, con esos caracteres eliminados.
Además, la forma en que lo estás haciendo va a ser un poco lenta, relativamente. También es probable que sea un poco confuso para los pythoneros experimentados, que verán una estructura doblemente anidada y pensarán por un momento que está pasando algo más complicado.
A partir de Python 2.6 y las versiones más recientes de Python 2.x *, puedes utilizar en su lugar str.translate
, (pero sigue leyendo para conocer las diferencias con Python 3):
line = line.translate(None, '!@#$')
o el reemplazo de expresiones regulares con re.sub
import re
line = re.sub('[!@#$]', '', line)
Los caracteres encerrados entre paréntesis constituyen una clase de caracteres. Cualquier carácter de linea
que esté en esa clase se sustituye por el segundo parámetro de sub
: una cadena vacía.
En Python 3, las cadenas son Unicode. kevpie menciona esto en un comentario en una de las respuestas, y está anotado en la documentación de str.translate
.
Cuando se llama al método translate
de una cadena Unicode, no se puede pasar el segundo parámetro que usamos arriba. Tampoco puedes pasar None
como primer parámetro, o incluso una tabla de traducción de string.maketrans
. En su lugar, se pasa un diccionario como único parámetro. Este diccionario mapea los valores ordinales de los caracteres (es decir, el resultado de llamar a ord
sobre ellos) a los valores ordinales de los caracteres que deberían reemplazarlos, o-usualmente para nosotros-None
para indicar que deberían ser eliminados.
Así que para hacer el baile anterior con una cadena Unicode se llamaría algo como
translation_table = dict.fromkeys(map(ord, '!@#$'), None)
unicode_line = unicode_line.translate(translation_table)
Aquí se utiliza dict.fromkeys
y map
para generar sucintamente un diccionario que contenga
{ord('!'): None, ord('@'): None, ...}
Aún más sencillo, como dice otra respuesta, crear el diccionario en el lugar:
unicode_line = unicode_line.translate({ord(c): None for c in '!@#$'})
* Para la compatibilidad con Python anteriores, puede crear una tabla de traducción "null" para pasarla en lugar de "None":
import string
line = line.translate(string.maketrans('', ''), '!@#$')
Aquí string.maketrans
se utiliza para crear una tabla de traducción, que es sólo una cadena que contiene los caracteres con valores ordinales 0 a 255.