假设我有以下两个列表:
x = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
y = [None,None,None,None,None,10,20,30,40,50,60,70,80,90,100]
我需要减去每个列表的相应元素(x [i] - y [i]),我想开始从x的第6个元素中减去6,这样y中的对应元素就不是null(None)。以下代码是我尝试过并得到的错误:
result = []
for i in x[5:]:
result.append(x[i] - y[i])
索引错误:列表索引超出范围
你应该这样做:
for val1, val2 in zip(x[5:], y[5:]):
result.append(val1 - val2)
要么
for val1, val2 in list(zip(x, y))[5:]:
result.append(val1 - val2)
您也可以跳过None
值,如下所示:
for val1, val2 in zip(x, y):
if val2 is not None: # can also check if val1 is not None if needed
result.append(val1 - val2)
你获得IndexError
的原因是你的循环中的i
被分配了x
列表的值(而不是!),并且你试图用这些值索引列表。因此,例如在循环i = 15
的最后一次,当该元素的索引仅为14
时。
你得到一个错误,因为你试图访问y[15]
(因为15是x[14]
的值)。
但y
只有15个元素,因为列表项从索引0开始,你得到list index out of range
。
一种更灵活的方法 - 只要你的两个列表具有相同的长度,就是使用zip
并跳过None
值:
x = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
y = [None,None,None,None,None,10,20,30,40,50,60,70,80,90,100]
result = []
for val_x, val_y in zip(x, y):
if(val_y is None):
continue
result.append(val_x - val_y)
print(result)
输出:
[-4, -13, -22, -31, -40, -49, -58, -67, -76, -85]
或者作为列表理解:
result = [ (val_x - val_y) for val_x, val_y in zip(x, y) if (val_y is not None) ]
你可以使用enumerate
例如:
x = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
y = [None,None,None,None,None,10,20,30,40,50,60,70,80,90,100]
result = []
for i, v in enumerate(x[5:], 5):
result.append(v - y[i])
print(result)
输出:
[-4, -13, -22, -31, -40, -49, -58, -67, -76, -85]
正如@meowgoesthedog在评论中所说,数组索引从0开始。
此外,由于你的2个列表大小相同,你可以压缩它们,使代码看起来更好,所以这里有一个带有压缩列表的解决方案:
result = []
for i, j in list(zip(x, y))[5:]:
result.append(i - j)
这是一个没有的解决方案:
result = []
for i in range(x[5:] - 1):
result.append(x[i] - x[j])
试试这个,它将在两个列表中处理“无”。我们无需手动跟踪它们。如果我们不需要前5,那么我们可以在减法上添加切片。
subtrct=[None if val is None else (val - (0 if y[index] is None else y[index])) for index, val in enumerate(x)]
你可以使用函数starmap()
和dropwhile()
:
from itertools import starmap, dropwhile
x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
y = [None, None, None, None, None, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
# substract corresponding elements
m = starmap(lambda x, y: x - y if y else None, zip(x, y))
# filter None
list(dropwhile(lambda x: not x, m))
# [-4, -13, -22, -31, -40, -49, -58, -67, -76, -85]