在Python中考虑此脚本:
>>> import math
>>> raw_data = [56.2, float('NaN'), 51.7, 55.3, 52.5, float('NaN'), 47.8]
>>> for i in range(len(raw_data)):
... print(i, raw_data[i])
... if math.isnan(raw_data[i]):
... del raw_data[i]
如您所见,我们将获得索引超出范围的错误,因此我得出结论,Python不会在每次迭代后检查条件,因为否则,当i
变为5
时,Python不会检查条件list也为5
,因此它不应首先进入循环主体,因为5
不小于5
。
因此,我得出的结论是,Python在第一次迭代时保存len(raw_data) = 7
,并且在每次迭代后检查是否i < 7
,并且不会每次都调用len()
函数。我说的对吗?
答案 0 :(得分:2)
range()是一个生成器函数,它在for循环的开始处进行一次评估,给出一个可迭代的:[0, 1, 2, 3, 4, 5, 6]
然后for循环对iterable中的每个项目运行一次。要实现您想要的目标,最好使用enumerate()
即。
for index, datum in enumerate(raw_data):
if math.isnan(datum):
del raw_data[index]
这将起作用(在python 2和3中),但是,通常认为编辑要迭代的列表是不好的做法-如果尝试通过按索引进行其他操作,则可能会得到一些奇怪的行为。相同的循环,因此您也可以考虑存储要删除的项目的索引,然后立即进行全部删除,以使代码更健壮。即。
indexes_to_delete = []
for index, datum in enumerate(raw_data):
if math.isnan(datum):
indexes_to_delete.append(index)
# go through the indexes in reverse, to make sure the deletions don't affect earlier indices
for index in sorted(indexes_to_delete, reverse=True):
del raw_data[index]