【问题标题】:In Python, are conditions in a loop re-evaluated before a new iteration is executed?在 Python 中,是否在执行新迭代之前重新评估循环中的条件?
【发布时间】:2019-03-17 17:59:07
【问题描述】:

对于python来说,对于for循环,是否会在重新迭代之前重新计算上界?

假设我有以下场景:

def remove(self,list,element):
     for x in range(0,len(list)):
           if somecondition:
               list.pop(x)

在执行for 循环的下一次迭代之前,是否会重新评估len(list) 条件? (正如我相信在某些语言中所做的那样,例如 Objective-C),否则,如果弹出多个元素,如果删除了 1 个元素,则会出现越界错误,并且最后一次迭代将尝试访问 list[len(list)-1]

我曾尝试自己对此进行调查,但每次结果都很混乱。

编辑:我相信我的问题与标记为重复的问题不同,因为我的问题是关于循环继续下一次迭代的条件,它可以很容易地添加一个元素而不是删除元素。

为了澄清,我的问题是 for 循环条件是否会重新检查下一次迭代之前提出的条件。

【问题讨论】:

  • 快速检查表明,如果您在迭代期间追加,len(some_list) 将不会被重新评估。 OTOH,如果您遍历列表本身并附加(for x in some_list:),那么迭代器就会混淆。除非您知道自己在做什么,否则在 Python 中通常会避免在迭代集合时对其进行变异。
  • 您尝试了哪些调查 - 很容易证明。
  • 您应该阅读有关 python 中的生成器的信息。 for 循环只是 try、iter=next(gen) do 循环、catch 的包装器。这提供了更深入的理解

标签: python list for-loop


【解决方案1】:

关于The for statement 的文档对此很清楚:

for 语句用于遍历序列的元素(如字符串、元组或列表)或其他 可迭代对象:

for_stmt ::= "for" target_list "in" expression_list ":" 套件 ["else" ":" 套件]

表达式列表计算一次;它应该产生一个可迭代的对象。创建了一个迭代器 expression_list 的结果。然后套件执行一次 迭代器提供的每个项目,按照返回的顺序 迭代器。

[强调我的]

因此,在您的情况下,range(0,len(list)) 只会被评估一次。

【讨论】:

  • 我明白了,我是否正确地假设 range(0,Y) 也是如此?给定 Y 在循环内被修改
  • 你是,任何表达式都是如此。 range 对象是一劳永逸地创建的,然后它将被迭代。
【解决方案2】:

是的,如果您尝试以下操作,您会看到 out of range 错误:

my_list = [0,1,2,3,4,5]
for x in range(0, len(my_list)):
    print("Length of my_list:", len(my_list))
    my_list.pop(x)

(您还应该避免使用像 list 这样的变量名,因为它会影响 Python 内置的 list。)

【讨论】:

  • 这更像是一个通用示例,而不是实际代码。
  • 你对什么说“是”?标题中问题的答案显然是“否”。这并不能证明 range() 在每次迭代中都被重新评估 - 恰恰相反(因为它不是)。而当x 变为 3 时,my_list 中只剩下 3 个元素,因此弹出超出范围。迭代固定为 6,迭代由错误终止,而不是由长度的重新评估。应避免回答“是”或“否”——问题很容易被改变以扭转意义。清楚地陈述你的主张会更安全。
【解决方案3】:

考虑以下代码:

i = 3

def test():
  global i ;
  i = i + 1
  return i

for x in range(0,test()):
  print( x, i )

每次迭代都会评估test() is callediis incremented, so the loop woul be endless iftest()`。然而输出是:

0 4
1 4
2 4
3 4

因此很明显test() 被评估了一次。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多