Gesplitst door komma en streep witruimte in Python

Ik heb een python-code die op een komma wordt gesplitst, maar de witruimte niet verwijdert:

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

Ik zou liever eindigen met witruimte die als volgt wordt verwijderd:

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

Ik ben me ervan bewust dat ik de lijst kan doorlopen en elk item kan strip() maar aangezien dit Python is, vermoed ik dat er een snellere, gemakkelijkere en elegantere manier is om dit te doen.


Antwoord 1, autoriteit 100%

Gebruik lijstbegrip — eenvoudiger en net zo gemakkelijk te lezen als een for-lus.

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

Zie:Python-documenten over lijstbegrip
Een goede uitleg van 2 seconden over het begrijpen van een lijst.


Antwoord 2, autoriteit 4%

Ik kwam om toe te voegen:

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

maar zag dat het al genoemd was door Jason Orendorff in een opmerking.

Toen ik de opmerking van Glenn Maynard in hetzelfde antwoord las, waarin werd gesuggereerd dat de kaart begrijpelijk was, begon ik me af te vragen waarom. Ik nam aan dat hij het bedoeld had om prestatieredenen, maar het kan natuurlijk ook om stilistische redenen zijn, of om iets anders (Glenn?).

Dus een snelle (mogelijk gebrekkige?) test op mijn doos waarbij de drie methoden in een lus werden toegepast, onthulde:

[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

waardoor map(str.strip, string.split(','))de winnaar wordt, hoewel het lijkt alsof ze allemaal in dezelfde marge zitten.

Zeker, hoewel een kaart (met of zonder lambda) om prestatieredenen niet per se moet worden uitgesloten, en voor mij is het minstens zo duidelijk als een lijstbegrip.

Bewerken:

Python 2.6.5 op Ubuntu 10.04


Antwoord 3, autoriteit 4%

Splitsen met een reguliere expressie. Opmerking Ik heb de casus algemener gemaakt met voorloopspaties. Het lijstbegrip is om de null-strings aan de voor- en achterkant te verwijderen.

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

Dit werkt zelfs als ^\s+niet overeenkomt:

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

Dit is waarom je ^\s+ nodig hebt:

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

Zie je de voorloopspaties in blah?

Verduidelijking: hierboven gebruikt de Python 3-interpreter, maar de resultaten zijn hetzelfde in Python 2.


Antwoord 4, autoriteit 3%

Verwijder gewoon de witruimte van de tekenreeks voordat u deze splitst.

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

Antwoord 5, autoriteit 2%

Ik weet dat dit al is beantwoord, maar als je dit vaak doet, zijn reguliere expressies misschien een betere manier om te gaan:

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

De \skomt overeen met elk witruimteteken en we vervangen het gewoon door een lege tekenreeks ''. U kunt hier meer informatie vinden: http://docs.python.org/library/ re.html#re.sub


Antwoord 6

map(lambda s: s.strip(), mylist)zou iets beter zijn dan expliciet herhalen. Of voor het hele ding tegelijk: map(lambda s:s.strip(), string.split(','))


Antwoord 7

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

dit werkt prima voor mij.


Antwoord 8

re(zoals in reguliere expressies) maakt splitsen op meerdere tekens tegelijk mogelijk:

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

Dit werkt niet goed voor uw voorbeeldreeks, maar werkt goed voor een door komma’s gescheiden lijst. Voor je voorbeeldstring kun je de re.split-kracht combineren om te splitsen op regex-patronenom een “split-op-dit-of-dat”-effect te krijgen.

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

Helaas is dat lelijk, maar een filterzal het lukken:

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

Voila!


Antwoord 9

s = 'bla, buu, jii'
sp = []
sp = s.split(',')
for st in sp:
    print st

Antwoord 10

import re
mylist = [x for x in re.compile('\s*[,|\s+]\s*').split(string)]

Gewoon een komma of ten minste één spaties met/zonder voorafgaande/opvolgende spaties.

Probeer het aub!


Antwoord 11

map(lambda s: s.strip(), mylist)zou iets beter zijn dan expliciet herhalen.
Of voor het hele ding tegelijk:

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

Dat is eigenlijk alles wat je nodig hebt.


Antwoord 12

In plaats van eerst de string te splitsen en je dan zorgen te maken over witruimte, kun je er eerst mee omgaan en het dan splitsen

string.replace(" ", "").split(",")

Other episodes