Reputation: 29
I have a list of strings and need to remove the sequences of empty strings only at the beginning and end of the list. I need to keep any empty strings that are between non-empty strings.
For example,
my_list = ['', '', 'Sam sits', '', 'Thinking of you.', '', 'All ideas bad.', '', '', '']
The output should be;
['Sam sits', '', 'Thinking of you.', '', 'All ideas bad.']
Most methods i have tried to use get rid of the blank lines in the middle too. Any advice would be greatly appreciated.
Upvotes: 2
Views: 1739
Reputation: 164613
You can calculate your indices first with next
and enumerate
. Then slice your list.
my_list = ['', '', 'Sam sits', '', 'Thinking of you.', '', 'All ideas bad.', '', '', '']
idx1 = next(i for i, j in enumerate(my_list) if j)
idx2 = -next(i for i, j in enumerate(reversed(my_list)) if j)
res = my_list[idx1: idx2 if idx2 !=0 else None]
print(res)
['Sam sits', '', 'Thinking of you.', '', 'All ideas bad.']
Upvotes: 4
Reputation: 51165
There is a more efficient way, but if you choose an element that isn't contained in the elements of the list, you can join
and strip
and split
which only removes the element from the front and back, preserving the empty elements in the middle.
>>> '-'.join(my_list).strip('-').split('-')
['Sam sits', '', 'Thinking of you.', '', 'All ideas bad.']
Extending this approach to concatenate longer runs of empty strings in the middle of a list to a single empty string:
import re
def remove_join(arr, el):
return re.split(r'\{}+()'.format(el), el.join(arr).strip(el))
>>> my_list = ['', '', 'test', '', '', '', 'test2', '', '']
>>> remove_join(my_list, '-')
['test', '', 'test2']
Upvotes: 6
Reputation: 77827
Look in the various list methods. You can use searches from left and right, and check to see whether they're the first and last elements. Conversely, simply remove the left-most element as long as it's an undesirable one. For instance:
while my_list[0] == '':
my_list.pop(0)
while my_list[-1] == '':
my_list.pop(-1)
For better efficiency (make a new list, but only one list alteration):
# First, form a Boolean list that identifies non-empty elements
has_content = [len(s) > 0 for s in my_list]
# Then find the left and right non-empty elements.
left = has_content.find(True) # find the left non-empty string
right = has_content.rfind(True) # find the right non-empty string
new_list = my_list[left:right+1]
This doesn't check edge cases, but gives the general idea.
Upvotes: 5