简体   繁体   English

Python 中的 for 循环条件检查是如何工作的?

[英]How does the for-loop condition checking works in Python?

Consider this script in Python :在 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]

As you can see we will get index out of range error, so I conclude that Python does not check the condition after each iteration because otherwise if it does, when i becomes 5 the length of list is 5 too so it should not enter the loop body at the first place since 5 is not lesser than 5 .正如你所看到的,我们会得到 index out of range 错误,所以我得出的结论是 Python 不会在每次迭代后检查条件,否则如果它这样做,当i变成5时,列表的长度也是5所以它不应该进入循环body 排在第一位,因为5不小于5

So I conclude that Python saves len(raw_data) = 7 at first iteration and it checks whether i < 7 after each iteration and does not call the len() function each time.所以我得出结论,Python 在第一次迭代时保存len(raw_data) = 7并且它在每次迭代后检查i < 7并且每次都不会调用len()函数。 Am I right ?我对吗 ?

range() is a generator function that is evaluated once at the beginning of the for loop giving an iterable: [0, 1, 2, 3, 4, 5, 6] The for loop then runs once for each item in the iterable. range() 是一个生成器函数,它在 for 循环开始时计算一次,给出一个可迭代对象: [0, 1, 2, 3, 4, 5, 6]然后 for 循环对可迭代对象中的每个项目运行一次。 To achieve what you are trying to do it would be better to use enumerate() ie.为了实现您想要做的事情,最好使用enumerate()即。

for index, datum in enumerate(raw_data):
    if math.isnan(datum):
        del raw_data[index]

This will work (in python 2 and 3), however, it is generally considered to be bad practice to edit a list that you are iterating over - you might get some strange behaviour if you try to do other operations by index in the same loop so you might also consider storing the indexes of items you wish to delete and then doing the deletions all at once afterwards to make your code more robust.这将起作用(在 python 2 和 3 中),但是,通常认为编辑正在迭代的列表是不好的做法 - 如果您尝试在同一循环中按索引执行其他操作,则可能会出现一些奇怪的行为因此,您还可以考虑存储您希望删除的项目的索引,然后在之后一次性执行所有删除操作,以使您的代码更加健壮。 ie. IE。

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]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM