¿Cómo dividir por coma y eliminar espacios en blanco en Python?

6 minutos de lectura

Avatar de usuario de Mr_Chimp
Sr_Chimpancé

Tengo un código de Python que se divide en coma, pero no elimina los espacios en blanco:

>>> string = "blah, lots  ,  of ,  spaces, here "
>>> mylist = string.split(',')
>>> print mylist
['blah', ' lots  ', '  of ', '  spaces', ' here ']

Preferiría terminar con espacios en blanco eliminados así:

['blah', 'lots', 'of', 'spaces', 'here']

Soy consciente de que podría recorrer la lista y eliminar () cada elemento pero, como se trata de Python, supongo que hay una forma más rápida, fácil y elegante de hacerlo.

Avatar de usuario de Sean Vieira
Sean Vieira

Use la comprensión de listas, más simple y tan fácil de leer como un for bucle.

my_string = "blah, lots  ,  of ,  spaces, here "
result = [x.strip() for x in my_string.split(',')]
# result is ["blah", "lots", "of", "spaces", "here"]

Ver: Documentos de Python sobre comprensión de listas

Una buena explicación de 2 segundos sobre la comprensión de listas.

  • ¡Super bien! Agregué un elemento de la siguiente manera para deshacerme de las entradas de la lista en blanco. > texto = [x.strip() for x in text.split(‘.’) if x != ”]

    – RandallShanePhD

    28 de julio de 2017 a las 19:41


  • @Sean: ¿era el código de Python inválido/incompleto su “intención original de la publicación”? Según los idiotas de la revisión, era: stackoverflow.com/review/suggested-edits/21504253. ¿Puede decirles lo contrario haciendo la corrección si están equivocados (otra vez)?

    – Forraje

    25 de noviembre de 2018 a las 10:19

  • El original fue copiado y pegado de un REPL (si no recuerdo mal) y el objetivo era comprender el concepto subyacente (usar la comprensión de listas para realizar una operación), pero tiene razón, tiene más sentido si ver esa lista por comprensión produce una nueva lista.

    – Sean Vieira

    26 de noviembre de 2018 a las 0:24

Avatar de usuario de Sean
sean

vine a agregar:

map(str.strip, string.split(','))

pero vio que Jason Orendorff ya lo había mencionado en un comentario.

Al leer el comentario de Glenn Maynard sobre la misma respuesta que sugiere listas de comprensión sobre el mapa, comencé a preguntarme por qué. Supuse que se refería a razones de rendimiento, pero, por supuesto, podría haberlo hecho por razones estilísticas o por algo más (¿Glenn?).

Entonces, una prueba rápida (¿posiblemente defectuosa?) en mi caja (Python 2.6.5 en Ubuntu 10.04) aplicando los tres métodos en un ciclo reveló:

$ time ./list_comprehension.py  # [word.strip() for word in string.split(',')]
real    0m22.876s

$ time ./map_with_lambda.py     # map(lambda s: s.strip(), string.split(','))
real    0m25.736s

$ time ./map_with_str.strip.py  # map(str.strip, string.split(','))
real    0m19.428s

haciendo map(str.strip, string.split(',')) el ganador, aunque parece que están todos en el mismo estadio.

Ciertamente, aunque el mapa (con o sin lambda) no necesariamente debe descartarse por razones de rendimiento, y para mí es al menos tan claro como la comprensión de una lista.

  • mejor respuesta list(map(str.strip, string.split(',')))

    – gndps

    30 de junio de 2022 a las 16:55

  • Más limpio y rápido

    – Mark Seagoe

    5 de agosto de 2022 a las 1:53

avatar de usuario de tbc0
por confirmar0

Dividir usando una expresión regular. Tenga en cuenta que hice el caso más general con espacios iniciales. La lista de comprensión consiste en eliminar las cadenas nulas al principio y al final.

>>> import re
>>> string = "  blah, lots  ,  of ,  spaces, here "
>>> pattern = re.compile("^\s+|\s*,\s*|\s+$")
>>> print([x for x in pattern.split(string) if x])
['blah', 'lots', 'of', 'spaces', 'here']

Esto funciona incluso si ^\s+ no coincide:

>>> string = "foo,   bar  "
>>> print([x for x in pattern.split(string) if x])
['foo', 'bar']
>>>

He aquí por qué necesita ^\s+:

>>> pattern = re.compile("\s*,\s*|\s+$")
>>> print([x for x in pattern.split(string) if x])
['  blah', 'lots', 'of', 'spaces', 'here']

¿Ves los espacios iniciales en bla?

Aclaración: arriba usa el intérprete de Python 3, pero los resultados son los mismos en Python 2.

  • Yo creo [x.strip() for x in my_string.split(',')] es más pitónico para la pregunta formulada. Tal vez haya casos en los que mi solución sea necesaria. Actualizaré este contenido si me encuentro con uno.

    – tbc0

    27 de julio de 2014 a las 23:32

  • Por que es ^\s+ ¿necesario? He probado tu código sin él y no funciona, pero no sé por qué.

    – laike9m

    21 de abril de 2015 a las 9:33

  • si uso re.compile("^\s*,\s*$")el resultado es [' blah, lots , of , spaces, here '].

    – laike9m

    21/04/2015 a las 15:40

  • @ laike9m, actualicé mi respuesta para mostrarte la diferencia. ^\s+ marcas. Como puedes ver por ti mismo, ^\s*,\s*$ tampoco devuelve los resultados deseados. Entonces, si desea dividir con una expresión regular, use ^\s+|\s*,\s*|\s+$.

    – tbc0

    21 de abril de 2015 a las 17:05


  • La primera coincidencia está vacía si el patrón principal (^\s+) no coincide, por lo que obtiene algo como [ ”, ‘foo’, ‘bar’ ] para la cadena “foo, bar”.

    – Steve McCauley

    01/04/2016 a las 12:36

Simplemente elimine el espacio en blanco de la cadena antes de dividirla.

mylist = my_string.replace(' ','').split(',')

Sé que esto ya ha sido respondido, pero si terminas haciendo esto muchas veces, las expresiones regulares pueden ser una mejor manera de hacerlo:

>>> import re
>>> re.sub(r'\s', '', string).split(',')
['blah', 'lots', 'of', 'spaces', 'here']

El \s coincide con cualquier carácter de espacio en blanco, y simplemente lo reemplazamos con una cadena vacía ''. Puedes encontrar más información aquí: http://docs.python.org/library/re.html#re.sub

  • Su ejemplo no funcionaría en cadenas que contienen espacios. “para, ejemplo esto, uno” se convertiría en “para”, “ejemplo esto”, “uno”. No digo que sea una MALA solución (funciona perfectamente en mi ejemplo), ¡solo depende de la tarea en cuestión!

    – Mr_Chimpancé

    1 de febrero de 2012 a las 16:11

  • ¡Sí, eso es muy correcto! Probablemente podría ajustar la expresión regular para que pueda manejar cadenas con espacios, pero si la comprensión de la lista funciona, diría que se mantenga;)

    –Brad Montgomery

    3 de febrero de 2012 a las 4:36

avatar de usuario de user470379
usuario470379

map(lambda s: s.strip(), mylist) sería un poco mejor que hacer un bucle explícitamente. O para todo a la vez: map(lambda s:s.strip(), string.split(','))

  • Su ejemplo no funcionaría en cadenas que contienen espacios. “para, ejemplo esto, uno” se convertiría en “para”, “ejemplo esto”, “uno”. No digo que sea una MALA solución (funciona perfectamente en mi ejemplo), ¡solo depende de la tarea en cuestión!

    – Mr_Chimpancé

    1 de febrero de 2012 a las 16:11

  • ¡Sí, eso es muy correcto! Probablemente podría ajustar la expresión regular para que pueda manejar cadenas con espacios, pero si la comprensión de la lista funciona, diría que se mantenga;)

    –Brad Montgomery

    3 de febrero de 2012 a las 4:36

Avatar de usuario de Zieng
Zieng

import re
result=[x for x in re.split(',| ',your_string) if x!='']

Esto funciona bien para mi.

¿Ha sido útil esta solución?