I want to remove all empty strings from a list of strings in python.
My idea looks like this:
while '' in str_list:
str_list.remove('')
Is there any more pythonic way to do this?
I want to remove all empty strings from a list of strings in python.
My idea looks like this:
while '' in str_list:
str_list.remove('')
Is there any more pythonic way to do this?
I guess list comprehensions
list = ["first", "", "second"]
[x for x in list if x]
Output: ['first', 'second']
Edit: Shortened as suggested
Loop through the existing string list and then check for a empty string, if it's not empty populate a new string list with the non-empty values and then replace the old string list with the new string list
I would use filter
:
str_list = filter(None, str_list) # fastest
str_list = filter(bool, str_list) # fastest
str_list = filter(len, str_list) # a bit of slower
str_list = filter(lambda item: item, str_list) # slower than list comprehension
Tests:
>>> timeit('filter(None, str_list)', 'str_list=["a"]*1000', number=100000)
2.4797441959381104
>>> timeit('filter(bool, str_list)', 'str_list=["a"]*1000', number=100000)
2.4788150787353516
>>> timeit('filter(len, str_list)', 'str_list=["a"]*1000', number=100000)
5.2126238346099854
>>> timeit('[x for x in str_list if x]', 'str_list=["a"]*1000', number=100000)
13.354584932327271
>>> timeit('filter(lambda item: item, str_list)', 'str_list=["a"]*1000', number=100000)
17.427681922912598
Depending on the size of your list, it may be most efficient if you use list.remove() rather than create a new list:
l = ["1", "", "3", ""]
while True:
try:
l.remove("")
except ValueError:
break
This has the advantage of not creating a new list, but the disadvantage of having to search from the beginning each time, although unlike using while '' in l
as proposed above, it only requires searching once per occurrence of ''
(there is certainly a way to keep the best of both methods, but it is more complicated).
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, ...)