Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove empty string from list

I just started Python classes and I'm really in need of some help. Please keep in mind that I'm new if you're answering this.

I have to make a program that takes the average of all the elements in a certain list "l". That is a pretty easy function by itself; the problem is that the teacher wants us to remove any empty string present in the list before doing the average.

So when I receive the list [1,2,3,'',4] I want the function to ignore the '' for the average, and just take the average of the other 4/len(l). Can anyone help me with this?

Maybe a cycle that keeps comparing a certain position from the list with the '' and removes those from the list? I've tried that but it's not working.

like image 537
user1783702 Avatar asked Oct 30 '12 12:10

user1783702


People also ask

How do I remove blank spaces from a list in Python?

strip() Python String strip() function will remove leading and trailing whitespaces. If you want to remove only leading or trailing spaces, use lstrip() or rstrip() function instead.

How do I remove only a string from a list in Python?

The remove() method removes the first matching element (which is passed as an argument) from the list. The pop() method removes an element at a given index, and will also return the removed item. You can also use the del keyword in Python to remove an element or slice from a list.


4 Answers

You can use a list comprehension to remove all elements that are '':

mylist = [1, 2, 3, '', 4]
mylist = [i for i in mylist if i != '']

Then you can calculate the average by taking the sum and dividing it by the number of elements in the list:

avg = sum(mylist)/len(mylist)

Floating Point Average (Assuming python 2)

Depending on your application you may want your average to be a float and not an int. If that is the case, cast one of these values to a float first:

avg = float(sum(mylist))/len(mylist)

Alternatively you can use python 3's division:

from __future__ import division
avg = sum(mylist)/len(mylist)
like image 197
Matt Avatar answered Nov 10 '22 22:11

Matt


You can use filter():

filter() returns a list in Python 2 if we pass it a list and an iterator in Python 3. As suggested by @PhilH you can use itertools.ifilter() in Python 2 to get an iterator.

To get a list as output in Python 3 use list(filter(lambda x:x != '', lis))

In [29]: lis = [1, 2, 3, '', 4, 0]

In [30]: filter(lambda x:x != '', lis)
Out[30]: [1, 2, 3, 4, 0]

Note to filter any falsy value you can simply use filter(None, ...):

>>> lis = [1, 2, 3, '', 4, 0]
>>> filter(None, lis)
[1, 2, 3, 4]
like image 21
Ashwini Chaudhary Avatar answered Nov 10 '22 22:11

Ashwini Chaudhary


The other answers show you how to create a new list with the desired element removed (which is the usual way to do this in python). However, there are occasions where you want to operate on a list in place -- Here's a way to do it operating on the list in place:

while True:
    try:
        mylist.remove('')
    except ValueError:
        break

Although I suppose it could be argued that you could do this with slice assignment and a list comprehension:

mylist[:] = [i for i in mylist if i != '']

And, as some have raised issues about memory usage and the wonders of generators:

mylist[:] = (i for i in mylist if i != '')

works too.

like image 2
mgilson Avatar answered Nov 10 '22 23:11

mgilson


itertools.ifilterfalse(lambda x: x=='', myList)

This uses iterators, so it doesn't create copies of the list and should be more efficient both in time and memory, making it robust for long lists.

JonClements points out that this means keeping track of the length separately, so to show that process:

def ave(anyOldIterator):
    elementCount = 0
    runningTotal = 0
    for element in anyOldIterator:
        runningTotal += element
        elementCount += 1
    return runningTotal/elementCount

Or even better

def ave(anyOldIterator):
    idx = None
    runningTotal = 0
    for idx,element in enumerate(anyOldIterator):
        runningTotal += element
    return runningTotal/(idx+1)

Reduce:

def ave(anyOldIterator):
    pieces = reduce(lambda x,y: (y[0],x[1]+y[1]), enumerate(anyOldIterator))
    return pieces[1]/(pieces[0]+1)

Timeit on the average of range(0,1000) run 10000 times gives the list comprehension a time of 0.9s and the reduce version 0.16s. So it's already 5x faster before we add in filtering.

like image 2
Phil H Avatar answered Nov 10 '22 22:11

Phil H