2010-08-18 47 views
3

我有一个列表,我想从其中删除不在其他列表中显示的项目。我试过以下内容: (无意)在列表中迭代时跳过项目

for w in common: 
     for i in range(1,n): 
      if not w in words[i]: 
       common.remove(w)
但是,这无法删除某些项目。添加打印语句
for w in common: 
     for i in range(1,n): 
         print w 
      if not w in words[i]: 
       print w 
       common.remove(w)
会导致某些w从不打印。关于发生了什么的任何想法?我假设答案很简单,我只是没有足够的Python知识,但我完全没有想法。

+0

为了提高效率,你应该设置'common'a'set',因为检查一个集合的成员比列表更快。 – katrielalex 2010-08-18 15:25:10

回答

3

您无法从正在迭代的列表中删除项目。尝试迭代列表的副本。

for w in common[:]: 
    for i in range(1,n): 
     if not w in words[i]: 
      common.remove(w) 
2

您正在修改列表的同时尝试遍历它。 您可以修改代码的第一行以遍历列表的副本(使用common [:])。

8

我认为你可以像这样简化您的语句:

filtered = filter(lambda x: x in words, common) 

这是检查每个元素以常见的是用语言存在和去除基于它。您可能需要尝试x not in words,具体取决于您期望的结果是什么,但我认为这应该接近。

我想添加一个其他的方法,也可能接近,但我需要查看您的初始列表的例子来完全测试它。

filtered = [x for x in common if x in words] 

- 编辑 - 我已经在列表理解的语法倒退,但在看到评论后发现它。谢谢!

+0

pythonic解决方案:) – Nicolas78 2010-08-18 15:13:25

+2

好,但我会更喜欢要么'过滤= [x为共同的x如果单词]或'过滤=过滤器(单词.__ contains__,common)'或使用'操作符.contains'而不是在这种情况下的lambda。可能是第一个。 – 2010-08-18 15:20:40

+0

它变pythonicer和pythonicer;) – Nicolas78 2010-08-18 15:24:48

3

the Python docs

它是不安全的修改上迭代在循环的顺序(这只能发生于可变序列类型,如列表)。如果您需要修改要迭代的列表(例如,复制选定项目),则必须遍历副本。

1

如果您删除(说)项目5,那么旧的项目6现在将是项目5.所以,如果你想移动到项目6,你会跳过它。

是否有可能在该列表上向后迭代?然后索引更改发生在您已处理的部分。