Remove empty strings from a list of strings
Become part of the top 3% of the developers by applying to Toptal https://topt.al/25cXVn
--
Music by Eric Matyas
https://www.soundimage.org
Track title: Underwater World
--
Chapters
00:00 Question
00:25 Accepted answer (Score 1486)
00:49 Answer 2 (Score 400)
01:14 Answer 3 (Score 100)
01:41 Answer 4 (Score 35)
02:26 Thank you
--
Full question
https://stackoverflow.com/questions/3845...
Accepted answer links:
[filter]: http://docs.python.org/library/functions...
Answer 2 links:
[list comprehension]: http://docs.python.org/tutorial/datastru...
--
Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...
--
Tags
#python #string #list
#avk47
--
Music by Eric Matyas
https://www.soundimage.org
Track title: Underwater World
--
Chapters
00:00 Question
00:25 Accepted answer (Score 1486)
00:49 Answer 2 (Score 400)
01:14 Answer 3 (Score 100)
01:41 Answer 4 (Score 35)
02:26 Thank you
--
Full question
https://stackoverflow.com/questions/3845...
Accepted answer links:
[filter]: http://docs.python.org/library/functions...
Answer 2 links:
[list comprehension]: http://docs.python.org/tutorial/datastru...
--
Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...
--
Tags
#python #string #list
#avk47
ACCEPTED ANSWER
Score 1554
I would use filter:
str_list = filter(None, str_list)
str_list = filter(bool, str_list)
str_list = filter(len, str_list)
str_list = filter(lambda item: item, str_list)
Python 3 returns an iterator from filter, so should be wrapped in a call to list()
str_list = list(filter(None, str_list))
ANSWER 2
Score 440
Using a list comprehension is the most Pythonic way:
>>> strings = ["first", "", "second"]
>>> [x for x in strings if x]
['first', 'second']
If the list must be modified in-place, because there are other references which must see the updated data, then use a slice assignment:
strings[:] = [x for x in strings if x]
ANSWER 3
Score 112
filter actually has a special option for this:
filter(None, sequence)
It will filter out all elements that evaluate to False. No need to use an actual callable here such as bool, len and so on.
It's equally fast as map(bool, ...)
ANSWER 4
Score 35
>>> lstr = ['hello', '', ' ', 'world', ' ']
>>> lstr
['hello', '', ' ', 'world', ' ']
>>> ' '.join(lstr).split()
['hello', 'world']
>>> filter(None, lstr)
['hello', ' ', 'world', ' ']
Compare time
>>> from timeit import timeit
>>> timeit('" ".join(lstr).split()', "lstr=['hello', '', ' ', 'world', ' ']", number=10000000)
4.226747989654541
>>> timeit('filter(None, lstr)', "lstr=['hello', '', ' ', 'world', ' ']", number=10000000)
3.0278358459472656
Notice that filter(None, lstr) does not remove empty strings with a space ' ', it only prunes away '' while ' '.join(lstr).split() removes both.
To use filter() with white space strings removed, it takes a lot more time:
>>> timeit('filter(None, [l.replace(" ", "") for l in lstr])', "lstr=['hello', '', ' ', 'world', ' ']", number=10000000)
18.101892948150635