【问题标题】:if statement in loop not working [duplicate]如果循环中的语句不起作用[重复]
【发布时间】:2013-05-26 17:16:10
【问题描述】:

对于我的一生,我无法弄清楚为什么我的 IF 语句没有被击中。在很多情况下,n 的余数 // 最后一个放在结果列表中的数字是 0。

n = 100
numbers = range(2, n)
results = []


results.append(numbers.pop(0))

print numbers

for n in numbers:
    if n % results[-1] == 0:
        print "If statement", numbers
        numbers.remove(n)
    else:
        print "Else statement", numbers
        numbers.remove(n)

【问题讨论】:

  • 尝试在 for 和 if 之后添加调试输出,例如print nprint results[-1]
  • 您正在从numbers 中删除项目,同时对其进行迭代。这将导致错误,因为迭代器计数器无论如何都会增加,并且您的循环将“跳过”项目。
  • 调用list.remove 会导致列表中的副作用 - 这会导致什么奇怪的事情?我会用remove重写这个 - 删除东西的反面是保留那些应该保留的东西:D在两个分支中删除似乎也很奇怪(=删除所有东西),但是..跨度>

标签: python


【解决方案1】:

问题是您在迭代列表时正在修改列表,因此所有偶数都被跳过。因此if 条件始终为False

for 循环跟踪索引,因此当您删除索引 i 处的项目时,i+1th 位置的下一个项目将移动到当前索引 (i),因此在下一次迭代中你实际上会选择i+2th 项。

for n in numbers[:]:   #iterate over a shallow copy of list
    if n % results[-1] == 0:
        print "If statement", numbers
        numbers.remove(n)
    else:
        print "Else statement", numbers
        numbers.remove(n)

例子:

>>> lis  = range(3,15)
>>> for x in lis:
...     print x
...     lis.remove(x)
...     
3
5
7
9
11
13

【讨论】:

    【解决方案2】:

    不要遍历要从中删除项目的列表。 for 循环创建一个列表迭代器,它通过递增计数器来跟踪当前项。但缩小列表意味着计数器将在循环迭代到循环迭代中指向错误的项目:

    >>> lst = range(5)
    >>> for i in lst:
    ...     lst.remove(i)
    ...     print i
    ... 
    0
    2
    4
    >>> lst
    [1, 3]
    

    发生的情况是,当您从列表 [0, 1, 2, 3, 4] 中删除 0 时,计数器会增加到项目 1,在现在更改的列表 [1, 2, 3, 4] 中指向值 2。从列表中删除2,迭代器计数增加到2,并且在更改列表中[1, 3, 4],这意味着循环中的下一个值是4,之后迭代器计数器计数超过结束和循环终止。

    如果您要从列表中删除 所有 项,请使用 while 循环:

    while numbers:
        n = numbers.pop()
        # do something with `n`
    

    如果您要删除 一些 项,另一种选择是创建一个浅拷贝:

    for n in numbers[:]:
         # ....
    

    现在您可以根据自己的喜好更改 numbers,因为 for 循环正在迭代副本。

    【讨论】:

      【解决方案3】:

      列表修改的另一种方式是做两遍:

      mod0 = []
      for n in numbers:
          mod0.append(n % results[-1] == 0)
      print [ n for n,m in zip(numbers, mod0) if m ]
      print [ n for n,m in zip(numbers, mod0) if not m ]
      

      【讨论】:

      • 有一个内置的方法来做这件事似乎很有用。我多次需要这样的东西。
      【解决方案4】:

      正如其他人回答的那样,问题是您正在迭代的列表的修改。我认为您真正尝试做的事情可以这样完成:

      results = [2]
      numbers = []
      
      n=100
      for n in range(3, n):
          if n % results[-1] == 0:
              results.append(n)
          else:
              numbers.append(n)
      

      这是一种获得二的幂的方法。另一种方法是:

      results = [2**n for n in range(1,7)]
      

      【讨论】:

        【解决方案5】:

        如果您想在循环时修改列表,请与我的小朋友while statement 见面:

        numbers=range(1,20)
        while numbers:
            if numbers[-1] % 2:
                print "If statement", numbers.pop()
            else:
                print "Else statement", numbers.pop()
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-03-28
          • 2016-01-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多