2017-06-05 246 views
1

我的问题看起来有点奇怪和容易,但我找不到满意的答案。我想迭代一个列表,并从中删除元素。当删除后在列表中剩下一个元素时,问题就会发生:循环不会在最后一个元素上迭代,就像列表为空一样。从列表中动态删除元素

,我在下面的例子中使用了..在..喜欢:

def test_remove(self): 
    """Test to remove all values from a list.""" 
    test = [4, 5] 
    [test.remove(i) for i in test] 
    print test 

我得到以下输出:

[5] 

这是否意味着迭代就像我现在这样在列表中不动态调整列表时,删除一个元素(同样的事情发生使用我在范围内())?或者只是因为我只是到达了i = len,所以我不能再走了吗?

我总是可以作弊并检查len是否等于1,但我想知道是否有更美丽的方式来做到这一点。

非常感谢。

回答

1

的问题是,当你删除列表中的项目,其他项目会改变其中的位置,导致跳过其中的一些,因为循环不断迭代。尝试更多的元素,你会看到如何跳过模式。

为了避免这种情况,您需要以不同的方式迭代列表,并且以我的观点为后向。

办法做到这可能是以下几点:

i = len(test)-1 
    while (i>=0): 
     del test[i] 
     i-=1 
    print(test) 
+0

是的,这是我最终做的。我以为能够避免这种循环结构。谢谢 :) – Ecterion

1

虽然在对该迭代进行修改时您无法在循环或列表理解中进行操作。最简单的是使用一个while循环

while len(test): 
    test.pop() 
+0

感谢您的回答。但在我的情况下,我不能使用.pop()为了从我的列表中删除一个项目,因为我必须从列表的开始处开始,并且在迭代它时可能会或可能不会删除项目。这取决于一些条件。 我想我现在会做一个简单的长度检查。 – Ecterion

0

它不只是最后一个元素,它是每个奇怪的元素 - 测试它在一个更长的列表。这是因为在删除元素时,所有其他元素都会移位。围绕它的最好方法可能是将不需要要删除的元素复制到新列表中。

0

当你的描述,你也可以去通过这样的方式。

ls = [1,2,3,4] 
ls_length = len(ls) 
i = 0 
condition_satisfied = True 
while ls_length: 
    if i<ls_length: 
     test_num = ls[i] 
     i = i + 1 
     if condition_satisfied: 
      ls.remove(test_num) 
      ls_length = len(ls) 
      i = 0 
print(ls) 
0

使用:

for (Iterator<String> iter = list.listIterator(); iter.hasNext();){ 
    String a = iter.next(); 
    if (...) {    
     iter.remove(); 
     }  
    } 

使用代码如上;它会工作。它为我去除了列表中的所有元素。