Podziel przecinkami i usuń białe spacje w Pythonie

Mam jakiś kod Pythona, który dzieli się na przecinki, ale nie usuwa białych znaków:

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

Wolałbym skończyć z białymi spacjami usuniętymi w ten sposób:

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

Zdaję sobie sprawę, że mógłbym zapętlić listę i usunąć() każdy element, ale ponieważ jest to Python, zgaduję, że istnieje szybszy, łatwiejszy i bardziej elegancki sposób na zrobienie tego.

Author: Eric Leschinski, 2010-11-01

11 answers

Użyj rozumienia listy-prostsze i równie łatwe do odczytania jak pętla for.

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

Zobacz też: Python docs on list Comprehension
Dobre 2-sekundowe Wyjaśnienie rozumienia listy.

 422
Author: Sean Vieira,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:34

Podziel za pomocą wyrażenia regularnego. Uwaga zrobiłem sprawę bardziej ogólne z wiodących spacji. Zrozumienie listy polega na usunięciu ciągów null Z Przodu iz tyłu.

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

To działa nawet jeśli ^\s+ nie pasuje:

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

Oto dlaczego potrzebujesz ^ \ s+:

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

Widzisz wiodące spacje w blah?

Wyjaśnienie: powyżej używa interpretera Pythona 3, ale wyniki są takie same w Pythonie 2.

 20
Author: tbc0,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-23 22:06:58

Wiem, że już na to odpowiedziałeś, ale jeśli skończysz robić to często, wyrażenia regularne mogą być lepszym rozwiązaniem:

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

\s pasuje do dowolnego znaku spacji, a my po prostu zastępujemy go pustym łańcuchem ''. Więcej informacji znajdziesz tutaj: http://docs.python.org/library/re.html#re.sub

 11
Author: Brad Montgomery,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-01 05:30:22

Przyszedłem dodać:

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

Ale widziałem, że już o tym wspomniał Jason Orendorff w komentarzu .

Czytając komentarz Glenna Maynarda w tej samej odpowiedzi sugerującej składanie listy nad mapą zacząłem się zastanawiać dlaczego. Założyłem, że miał na myśli ze względów performatywnych, ale oczywiście mógł mieć na myśli ze względów stylistycznych, albo coś innego (Glenn?).

Tak szybko (ewentualnie wadliwe?) test na moim pudełku stosując trzy metody w pętli revealed:

[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

Czyniąc map(str.strip, string.split(',')) zwycięzcą, chociaż wydaje się, że wszyscy są w tym samym polu gry.

Z pewnością jednak mapa (z lambdą lub bez) nie powinna być wykluczona ze względów wydajnościowych, a dla mnie jest co najmniej tak jasna, jak zrozumienie listy.

Edit:

Python 2.6.5 na Ubuntu 10.04

 11
Author: Sean,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:34

Po prostu usuń białą spację z łańcucha, zanim go podzielisz.

mylist = my_string.replace(' ','').split(',')
 6
Author: user489041,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-01 18:26:37
import re
result=[x for x in re.split(',| ',your_string) if x!='']
To mi pasuje.
 2
Author: Zieng,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-02 11:57:50

re (jak w wyrażeniach regularnych) pozwala na dzielenie na wiele znaków jednocześnie:

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

To nie działa dobrze dla przykładowego ciągu znaków, ale działa dobrze dla listy rozdzielonej przecinkami. Dla przykładowego ciągu można połączyć re.podziel moc, aby podzielić na wzorce regex , aby uzyskać efekt "podziel na to lub tamto".

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

Niestety, to brzydkie, ale filter wystarczy:

$ filter(None, re.split('[, ]',string))
['blah', 'lots', 'of', 'spaces', 'here']
Voila!
 2
Author: Dannid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-18 19:08:53

map(lambda s: s.strip(), mylist) byłoby to trochę lepsze niż jawne zapętlenie. Lub za całość na raz: map(lambda s:s.strip(), string.split(','))

 1
Author: user470379,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-01 17:31:29
s = 'bla, buu, jii'

sp = []
sp = s.split(',')
for st in sp:
    print st
 1
Author: Parikshit Pandya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-31 02:53:27
import re
mylist = [x for x in re.compile('\s*[,|\s+]\s*').split(string)

Po prostu, przecinek lub przynajmniej jedna biała spacja z / bez poprzedzających / następnych białych spacji.

Proszę spróbować!

 1
Author: GyuHyeon Choi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-05 02:49:36

map(lambda s: s.strip(), mylist) byłoby to trochę lepsze niż jawne zapętlenie.
Albo za całość na raz:

map(lambda s:s.strip(), string.split(','))
To wszystko, czego potrzebujesz.
 0
Author: DJbigpenis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-09 12:52:22