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.
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.
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.
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)
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)
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]
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With