多个条件if语句字符串关键字:in,not in

时间:2014-05-19 21:33:03

标签: python

我有一个字符串列表。我正在尝试删除具有某些子字符串的元素。如果我使用以下内容,则只删除包含“Cantab”的元素:

for line in merged:
    if 'Duke' in line and 'Sir' not in line or 'Cantab' in line or 'Rick' in line:
        merged.remove(line)           

如果我尝试分解条件,我的目标结果无法实现,但我成功删除了包含Duke但不包括Sir Duke的元素。:

if 'Duke' in line and 'Sir' not in line:
    merged.remove(line)

这可以按预期工作:

if 'Duke' in line and 'Sir' not in line:
    merged.remove(line)
elif 'Cantab' in line:
    merged.remove(line)

但以下只删除包含'Cantab'的元素!!!:

if 'Duke' in line and 'Sir' not in line:
    merged.remove(line)
elif 'Cantab' in line:
    merged.remove(line)
elif 'Rick' in line:
    merged.remove(line)

我在找出这里的逻辑时遇到了麻烦。谢谢!

1 个答案:

答案 0 :(得分:4)

通常,不要迭代列表同时从列表中删除项目。它会移动尚未迭代的项目的内部索引,因此并非所有项目都会被迭代。

您可以通过循环遍历merged

的副本来解决问题
for line in list(merged):

此示例说明了问题:

merged = ['Cantab', 'Duke', 'Cantab', 'Duke', 'Cantab', 'Duke']
for line in merged:
    print(line)
    if 'Duke' in line and 'Sir' not in line or 'Cantab' in line or 'Rick' in line:
        merged.remove(line)           
print(merged)

打印

Cantab  # only the Cantab lines are being iterated over!
Cantab
Cantab
['Duke', 'Duke', 'Duke']

考虑循环的第一次迭代。当line等于Cantab时,第一个Duke的内部索引为1.但删除Cantab后,第一个Duke的内部索引变为0.但Python将循环索引提升为1!现在第二个 Cantab位于索引1处,因此第一个Duke被完全跳过。


或者,您可以通过向后迭代列表来修复问题,而无需复制merged。以这种方式完成,删除merged中的当前项是安全的,因为尚未修改的项目的位置未被修改:

merged = ['Cantab', 'Duke']*3
for i in range(len(merged)-1, -1, -1):
    line = merged[i]
    if 'Duke' in line and 'Sir' not in line or 'Cantab' in line or 'Rick' in line:
        del merged[i] 
print(merged)

打印

[]

根据需要。