p seth
p seth

Reputation: 29

How to remove blank elements at the beginning and end of a list Python

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

Answers (3)

jpp
jpp

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

user3483203
user3483203

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

Prune
Prune

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

Related Questions