This seems like it would be simple, but I am having an issue with setting negative numbers in a list to 0. Here is my code:
def subtract_lists(list1, list2):
list3 = list()
for i in range(0,len(list1)):
list3.append(list1[i]-list2[i])
if i < 0:
i = 0
else:
i = i
return list3
I am using this function when making stacked bar charts with matplotlib. Essentially, some values in list2 are larger than values in list1. For the data I have it doesn't make sense to have negative values. Essentially anything with a negative value would just plot as one solid bar.
EDIT: Just wanted to add that the top of the graph is list3.
EDIT 2: Thank you everyone for the help. I ended up using this due to the simplicity:
def subtract_lists(list1, list2):
list3 = list()
for i in range(0,len(list1)):
list3.append(max(list1[i]-list2[i], 0))
return list3
However I appreciate all the solutions and help, I am going to try some of the other examples just for a learning experience.
One way to do it is to change the list to a numpy array. Then the subtraction is easy and clear, plus you can use numpy.clip to change negative values to 0. numpy arithmetic is also much, much faster (if that's a concern in this case, which seems unlikely) than iterating over python lists.
import numpy as np
ar1 = np.array(list1)
ar2 = np.array(list2)
ar3 = np.clip(ar1 - ar2, 0, None)
If you don't want to use numpy, then just change this line
list3.append(list1[i] - list2[i])
to this
list3.append(max(list1[i] - list2[i], 0))
Finally, when you're iterating over lists to make a new list, it is far more idiomatically python to use a list comprehension:
list3 = [max(item1 - item2, 0) for item1, item2 in zip(list1, list2)]
Of course, if the lists are moderately large, then you have to concern yourself with the fact that zip actually makes a copy of the lists. So if memory usage is too large with zip, you can use izip from the itertools module. It's just a drop-in replacement (in this case) for zip:
from itertools import izip
list3 = [max(item1 - item2, 0) for item1, item2 in izip(list1, list2)]
You are setting i to zero, not the content of list3[i].
if list3[i] < 0:
list3[i] = 0
Your else block is setting i=i, which does nothing. You are also lacking one level of indentation for this check, the correct indentation would look like this:
def subtract_lists(list1, list2):
list3 = list()
for i in range(0,len(list1)):
list3.append(list1[i]-list2[i])
if list3[i] < 0:
list3[i] = 0
return list3
However, I think it would be clearer to write the function like this:
def subtract_lists(list1, list2):
list3 = []
for a,b in zip(list1, list2):
diff = a - b
list3.append(diff if diff > 0 else 0)
return list3
There are of course more concise solutions (check DrV's answer).
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