7.3 for语句 The for statement

The for statement is used to iterate over the elements of a sequence (such as a string, tuple or list) or other iterable object:

for语句用于迭代有序类型或其它可迭代对象的元素(像串, 元组或列表):

for_stmt  ::=  "for" target_list "in" expression_list ":" suite
    ["else" ":" suite]
Download entire grammar as text.

The expression list is evaluated once; it should yield a sequence. The suite is then executed once for each item in the sequence, in the order of ascending indices. Each item in turn is assigned to the target list using the standard rules for assignments, and then the suite is executed. When the items are exhausted (which is immediately when the sequence is empty), the suite in the else clause, if present, is executed, and the loop terminates.

表达式表仅被计算一次, 它应该生成一个有序类型对象.语句序列对每个有序类型对象的元素按索引升序执行一次.每个元素使用标准的赋值规则依次赋给循环控制对象表, 然后执行语句序列.当迭代完毕后(当有序类型对象为空立即结束循环), 就执行else子句(如果给出), 然后循环结束.

A break statement executed in the first suite terminates the loop without executing the else clause's suite. A continue statement executed in the first suite skips the rest of the suite and continues with the next item, or with the else clause if there was no next item.

在第一个语句序列中的break语句可以实现不执行else子句而退出循环.在第一个语句序列中的continue语句可以跳过该子句的其余部分, 直接进行下个元素的计算, 或者当迭代完毕后进入else子句.

The suite may assign to the variable(s) in the target list; this does not affect the next item assigned to it.

语句序列可以对循环控制对象表中的变量赋值, 这不影响for语句赋下一项元素给它.

The target list is not deleted when the loop is finished, but if the sequence is empty, it will not have been assigned to at all by the loop. Hint: the built-in function range() returns a sequence of integers suitable to emulate the effect of Pascal's for i := a to b do; e.g., range(3) returns the list [0, 1, 2].

在循环结束后,这个循环控制对象表没有删除, 但是如果有序类型对象为空, 它在循环根本就不会被该有序类型对象赋值.小技巧: 内建函数range()返回一个整数列表, 可以用于模拟Pascal语言中的for i := a to b的行为, 例如range返回在列表 [0, 1, 2].

Warning: There is a subtlety when the sequence is being modified by the loop (this can only occur for mutable sequences, i.e. lists). An internal counter is used to keep track of which item is used next, and this is incremented on each iteration. When this counter has reached the length of the sequence the loop terminates. This means that if the suite deletes the current (or a previous) item from the sequence, the next item will be skipped (since it gets the index of the current item which has already been treated). Likewise, if the suite inserts an item in the sequence before the current item, the current item will be treated again the next time through the loop. This can lead to nasty bugs that can be avoided by making a temporary copy using a slice of the whole sequence, e.g.,

警告:如果在循环要修改有序类型对象(仅对可变类型而言, 即列表)的话, 这里有一些要注意的地方.有一个内部计数器用于跟踪下一轮循环使用哪一个元素, 并且每次迭代就增加一次.当这个计数器到达有序类型对象的长度时该循环就结束了.这意味着如果语句序删除一个当前元素(或前一个元素)时, 下一个元素会被跳过去(因为当前索引值的元素已经处理过了).另一方面, 如果在当前元素前插入一个元素, 则当前元素会下一轮循环被再次重复处理.这可能会导致难以觉察的错误.但可以通过使用含有整个有序类型对象的片断而生成的临时拷贝避免这个问题, 例如,

for x in a[:]:
    if x < 0: a.remove(x)