2014-05-19 41 views
1

我有一個字符串列表。我試圖刪除具有特定子字符串的元素。如果我用下面,被刪除只包含「坎特」元素:多條件if語句字符串關鍵字:in,不在

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

如果我嘗試向上突破的條件,我的目標結果沒有實現,但我成功地刪除包含杜克的元素,但不杜克爵士:

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) 

但下面只刪除含有 '坎特' 元素!!!:

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) 

我在這裏遇到麻煩搞清楚的邏輯。謝謝!

+0

您正在使用一個'if語句',這意味着如果其中一個分支被採用,則其餘的將不被考慮。相反,嘗試將每個條件分隔成一個單獨的'if語句'。即用'if'代替'elif's。看看是否有幫助。 – s16h

回答

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) 

打印

[] 

達到目標。

+0

偷偷摸摸!是否有創建副本循環而不是完整分片的更明顯的方法? –

+1

或者,遍歷循環*向後*。然後刪除最後一項是安全的。 – unutbu

+0

謝謝。這是我以前犯的一個愚蠢的錯誤。感謝您的快速解決方案。 –