2012-10-18 75 views
4

我有一个列表,我试图删除其中有'pie'的元素。这就是我所做的。在列表元素中搜索子字符串删除元素(Python)

['applepie','orangepie', 'turkeycake'] 
for i in range(len(list)): 
    if "pie" in list[i]: 
     del list[i] 

我不断收到列表索引超出范围,但是当我将del改为打印语句时,它打印出的元素很好。

+0

如果“pie”始终处于末尾,则可以使用字符串的endswith方法。如果这是你想要做的,它会更有效率(对于长字符串,对于短字符串它几乎是相同的)并且更清楚。 (在旁注:也存在'startswith')。 – Bakuriu

回答

1

为什么出现错误的原因是因为您在删除某些东西时更改了列表的长度!

例子:

first loop: i = 0, length of list will become 1 less because you delete "applepie" (length is now 2) 
second loop: i = 1, length of list will now become just 1 because we delete "orangepie" 
last/third loop: i = 2, Now you should see the problem, since i = 2 and the length of the list is only 1 (to clarify only list[0] have something in it!). 

因此,而使用这样的:

for item in in list: 
    if "pie" not in item: 
     new list.append(item) 
2

删除元素的迭代过程中,改变了大小,从而导致IndexError。

你可以重写你的代码(使用列表综合)

L = [e for e in L if "pie" not in e] 
0

另一个但更长的方法是记下,你遇到的馅饼索引和删除后的第一个这些元素的循环

+0

您仍有同样的问题 - 除非您按相反顺序删除元素。但是这仍然没有效率,因为删除一个元素意味着所有后面的元素都必须每次都被洗牌。创建一个新列表非常有效,您不会复制元素,只需创建额外的引用即可。 –

+0

好点。同意 –

6

而不是从列表中删除一个项目你遍历,尝试用Python创建的漂亮list comprehension syntax一个新的列表:

foods = ['applepie','orangepie', 'turkeycake'] 
pieless_foods = [f for f in foods if 'pie' not in f] 
+0

'食品= ['applepie','orangepie','turkeycake'] pie_foods = [f for f'if'pie'not in f]' (不确定'不在'是不是语法 –

+0

@AJ。谢谢,感觉错了 - 我纠正了这个问题 –

+0

非常短而紧凑的答案。将是最简单的解决方案 –

2

喜欢的东西:

stuff = ['applepie','orangepie', 'turkeycake'] 
stuff = [item for item in stuff if not item.endswith('pie')] 

修改正在迭代的对象应被视为禁止。