这看起来很简单,但我在将列表中的负数设置为0时出现问题。这是我的代码:
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
在使用matplotlib制作堆积条形图时,我正在使用此功能。实质上,list2中的某些值大于list1中的值。对于我所拥有的数据,有负值是没有意义的。基本上任何具有负值的东西都只是绘制成一个实心条。
编辑:只想添加图表的顶部是list3。
编辑2:谢谢大家的帮助。由于简单,我最终使用了这个:
def subtract_lists(list1, list2):
list3 = list()
for i in range(0,len(list1)):
list3.append(max(list1[i]-list2[i], 0))
return list3
但是我很欣赏所有的解决方案和帮助,我将尝试一些其他的例子来获取学习经验。
答案 0 :(得分:3)
一种方法是将列表更改为numpy
array
。然后减法很简单明了,另外你可以使用numpy.clip
将负值更改为0. numpy
算术运算速度也快得多(如果在这种情况下需要关注,那么不可能)而不是迭代python列表。
import numpy as np
ar1 = np.array(list1)
ar2 = np.array(list2)
ar3 = np.clip(ar1 - ar2, 0, None)
如果您不想使用numpy,那么只需更改此行
即可list3.append(list1[i] - list2[i])
到这个
list3.append(max(list1[i] - list2[i], 0))
最后,当您在列表上进行迭代以创建新列表时,使用列表解析更加惯用python:
list3 = [max(item1 - item2, 0) for item1, item2 in zip(list1, list2)]
当然,如果列表中等大,那么您必须关注zip
实际制作列表副本的事实。因此,如果zip
的内存使用量过大,您可以使用izip
模块中的itertools
。它只是zip
的替代品(在这种情况下):
from itertools import izip
list3 = [max(item1 - item2, 0) for item1, item2 in izip(list1, list2)]
答案 1 :(得分:2)
您将i
设置为零,而不是list3[i]
的内容。
if list3[i] < 0:
list3[i] = 0
您的else
阻止正在设置i=i
,但不执行任何操作。对于此检查,您也缺少一级缩进,正确的缩进将如下所示:
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
但是,我认为编写这样的函数会更清楚:
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
当然有更简洁的解决方案(请查看DrV&#39的回答)。
答案 2 :(得分:1)
list3 = []
for i in range(len(list1)):
list3.append(max(list1[i] - list2[i], 0))
或
list3 = [ max(li1-li2, 0) for li1, li2 in zip(list1, list2) ]
zip
允许同时迭代两个列表,以便li1
和li2
列表项构成列表的相同位置。 IMO这是最恐怖的方式,在这种情况下,如果我们有两个列表,它可能也是最快的方式。 max
负责处理负数,因为零大于li1-li2
并被放入list3
。
jsw
给出的解决方案是一个不错的解决方案,但是从列表到ndarray
(NumPy数组)的转换是一个缓慢的解决方案。当然,NumPy(不幸的是)不是标准Python发行版的一部分。