Remove empty strings from a list of strings
--------------------------------------------------
Rise to the top 3% as a developer or hire one of them at Toptal: https://topt.al/25cXVn
--------------------------------------------------
Music by Eric Matyas
https://www.soundimage.org
Track title: Mysterious Puzzle
--
Chapters
00:00 Remove Empty Strings From A List Of Strings
00:19 Answer 1 Score 440
00:39 Accepted Answer Score 1554
00:58 Answer 3 Score 112
01:17 Answer 4 Score 35
01:47 Thank you
--
Full question
https://stackoverflow.com/questions/3845...
--
Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...
--
Tags
#python #string #list
#avk47
Rise to the top 3% as a developer or hire one of them at Toptal: https://topt.al/25cXVn
--------------------------------------------------
Music by Eric Matyas
https://www.soundimage.org
Track title: Mysterious Puzzle
--
Chapters
00:00 Remove Empty Strings From A List Of Strings
00:19 Answer 1 Score 440
00:39 Accepted Answer Score 1554
00:58 Answer 3 Score 112
01:17 Answer 4 Score 35
01:47 Thank you
--
Full question
https://stackoverflow.com/questions/3845...
--
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