web-dev-qa-db-fra.com

Diviser par virgule et effacer les espaces dans Python

J'ai du code python qui se divise en virgule, mais ne supprime pas les espaces:

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

Je préférerais me retrouver avec des espaces supprimés comme ceci:

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

Je suis conscient que je pourrais parcourir la liste et strip () chaque élément, mais comme il s'agit de Python, je suppose qu'il existe un moyen plus rapide, plus simple et plus élégant de le faire.

297
Mr_Chimp

Utilisez la compréhension de liste - plus simple et aussi facile à lire qu’une boucle for.

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

Voir: Documents Python sur la compréhension de la liste
ne bonne explication de 2 secondes sur la compréhension de la liste.

511
Sean Vieira

Fractionner en utilisant une expression régulière. Notez que j'ai rendu le cas plus général avec les espaces de début. La compréhension de la liste consiste à supprimer les chaînes nulles au début et à la fin.

>>> 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']

Cela fonctionne même si ^\s+ ne correspond pas:

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

Voici pourquoi vous avez besoin de ^\s +:

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

Voir les espaces principaux en blah?

Clarification: ci-dessus utilise l'interprète Python 3, mais les résultats sont les mêmes dans Python 2.

21
tbc0

Je suis venu ajouter:

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

mais j'ai vu qu'il avait déjà été mentionné par Jason Orendorff dans n commentaire .

En lisant le commentaire de Glenn Maynard dans la même réponse, suggérant une compréhension de la liste par rapport à la carte, je commençais à me demander pourquoi. J'ai supposé qu'il voulait dire pour des raisons de performance, mais bien sûr, il aurait pu vouloir dire pour des raisons stylistiques ou autre chose (Glenn?).

Donc, un test rapide (éventuellement imparfait?) Sur ma boîte en appliquant les trois méthodes en boucle a révélé:

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

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

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

map(str.strip, string.split(',')) est le vainqueur, bien qu'il semble qu'ils soient tous dans le même stade.

Certes, une carte (avec ou sans lambda) ne doit pas nécessairement être exclue pour des raisons de performance, et pour moi, elle est au moins aussi claire que la compréhension par liste.

Modifier:

Python 2.6.5 sur Ubuntu 10.04

14
Sean

Supprimez simplement l'espace blanc de la chaîne avant de la scinder.

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

Je sais que cela a déjà été répondu, mais si vous finissez souvent, les expressions régulières peuvent être une meilleure solution:

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

Le \s correspond à n'importe quel caractère d'espacement et nous le remplaçons simplement par une chaîne vide ''. Vous pouvez trouver plus d'informations ici: http://docs.python.org/library/re.html#re.sub

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

cela fonctionne bien pour moi.

2
Zieng

re (comme dans les expressions régulières) permet de séparer plusieurs caractères à la fois:

$ string = "blah, lots  ,  of ,  spaces, here "
$ re.split(', ',string)
['blah', 'lots  ', ' of ', ' spaces', 'here ']

Cela ne fonctionne pas bien pour votre exemple de chaîne, mais fonctionne bien pour une liste séparée par des virgules. Pour votre exemple de chaîne, vous pouvez combiner le pouvoir re.split pour scinder modèles de regex pour obtenir un effet "scission sur ou ceci".

$ re.split('[, ]',string)
['blah',
 '',
 'lots',
 '',
 '',
 '',
 '',
 'of',
 '',
 '',
 '',
 'spaces',
 '',
 'here',
 '']

Malheureusement, c'est moche, mais un filter fera l'affaire:

$ filter(None, re.split('[, ]',string))
['blah', 'lots', 'of', 'spaces', 'here']

Voila!

2
Dannid
s = 'bla, buu, jii'

sp = []
sp = s.split(',')
for st in sp:
    print st
2
Parikshit Pandya
import re
mylist = [x for x in re.compile('\s*[,|\s+]\s*').split(string)

Simplement, une virgule ou au moins un espace blanc avec/sans espace blanc précédent/suivant.

S'il vous plaît essayez!

1
GyuHyeon Choi

map(lambda s: s.strip(), mylist) serait un peu mieux que la boucle explicitement. Ou pour tout à la fois: map(lambda s:s.strip(), string.split(','))

1
user470379

map(lambda s: s.strip(), mylist) serait un peu mieux que la boucle explicitement.
Ou pour tout à la fois:

map(lambda s:s.strip(), string.split(','))

C'est fondamentalement tout ce dont vous avez besoin.

0
DJbigpenis