【问题标题】:Approach to avoid overlooking elements while looping over lists and popping elements from the same list避免在循环列表和从同一列表中弹出元素时忽略元素的方法
【发布时间】:2017-10-04 16:18:23
【问题描述】:

编程时的一个常见场景是,给定一个列表,当条件为真时,我们必须遍历该列表和同一列表中的pop() 元素。

现在,在这种情况下,例如我有一个列表 a = [1, 2, 3, 4, 5, 6, 7, 9, 10],问题要求从列表中删除所有奇数元素。

所以,我只是采取这样的方法。

for (int i=0; i<=a.length; i++) {
    if (a[i]%2 != 0) {
        a.removeElementAtIndex(i);
    }
}

现在,这在a 列表中的6 之前都可以正常工作。

之后,循环索引将是 6 并且将引用列表中的 7。由于7 是一个奇数,它会将7 从列表中删除。

现在,循环索引将是7,它将指向列表中的10。并且列表中的元素 9 现在位于索引 6 处,该索引已被循环检查。

所以,这种方法会导致错误!

问题:一种不会导致上述情况的方法,并且仅使用一个列表并且仅在元素上循环一次。

【问题讨论】:

  • 听起来你在用JS。为什么不使用 array.filter()?这将遍历 a 中的所有元素并仅返回与条件匹配的那些值。所以 var results = a.filter(function(element) { //如果元素是偶数则返回 true 的逻辑});
  • @nraduka 它通过这样做创建了一个新列表,他想就地更改列表。
  • 如果您真的坚持不创建新列表 - 您可以在每次删除项目时减少 i
  • 嗯,好的。我误解了@Dean Fenster 的想法是正确的

标签: list loops conditional-statements


【解决方案1】:

一般来说,通常的做法是不更改您当前正在迭代的列表。但要使用新列表,或使用filter 方法。

但是,您可以在每次像这样删除项目时递减 i 计数器:

for (int i=0; i<=a.length; i++) {
    if (a[i]%2 != 0) {
        a.removeElementAtIndex(i);
        i--;
    }
}

它应该可以工作,但前提是您使用a.length 之类的东西,而不是给定时间列表中大小的快照。

编辑:在 python 中,因为没有 c 样式的 for,它看起来像这样:

In [3]: i = 0

In [4]: a = list(range(12))

In [5]: while i < len(a):
   ...:     if a[i] % 2 != 0:
   ...:         a.remove(a[i])
   ...:         i -= 1
   ...:     i += 1
   ...:     

In [6]: a
Out[6]: [0, 2, 4, 6, 8, 10]

【讨论】:

  • 这是一个无限循环!自己试试吧!并且 i-- 导致 i 在 JS 中减少。但是在像 python 这样的语言中,i 仅在当前迭代中减少。下一次迭代它只是它应该正常的值。
  • python 没有这种 c 样式。所以,很明显,它与 python 无关。
  • @Arunava 您使用的是什么语言。我给出了一般方法,因为您没有指定语言。
  • 我使用了递归。要执行此操作。对于我删除的每个项目,我检查了下一个元素。如果它也很奇怪,我会把它弹出来。
  • Python @DeanFenster
猜你喜欢
  • 2022-01-06
  • 1970-01-01
  • 1970-01-01
  • 2016-07-21
  • 1970-01-01
  • 1970-01-01
  • 2011-04-23
  • 1970-01-01
  • 2023-03-28
相关资源
最近更新 更多