2014-10-04 82 views
0

我有兩個字符串列表。兩個字符串列表:從列表A中刪除包含列表B中的任何字符串的字符串?

filters = ['foo', 'bar'] 

wordlist = ['hey', 'badge', 'foot', 'bar', 'cone'] 

我想刪除包含過濾器的單詞表中的每個單詞。

def filter_wordlist(filters, wordlist): 

    for word in wordlist: 
     if word contains any string from filters, remove it from the wordlist 

    return wordlist 

所以這個過濾函數會返回['hey', 'badge', 'cone']。它刪除bar,因爲barfilters。它刪除了foot,因爲它包含字符串foo

我嘗試這樣做:

for word in wordlist: 
    for f in filters: 
     if f in word: 
      wordlist.remove(word) 

但它始終返回ValueError: list.remove(x): x not in list。所以我試圖用一系列越來越令人沮喪的嘗試/除了塊以外的其他東西包裹它,但是沒有發現那個Gopher洞沒有起作用。我在刪除命令下面添加了一條break語句,但那是...點點滴滴。看起來像wordlist末尾的項目沒有正確過濾。

所以我改變了戰術,以這樣的:

for f in filters: 
    for word in wordlist: 
     if f in word: 
      wordlist.remove(word) 

這是參差不齊像以前一樣。

所以,我想這一點:

for word in wordlist: 
    if any(f in word for f in filters): 
     wordlist.remove(word) 

而現在它肯定讓我感到憤怒。參差不齊。到目前爲止,我已經意識到發生了什麼 - 使用remove()正在改變列表,因爲我正在迭代它,這就是搞砸了迭代。

這看起來應該很簡單。我有兩個字符串列表。採取的所有項目名單A.如果任何這些項目都含有由B的任何項目,從列表A.

刪除項這是一個工作解決方案,我終於得到了:

keepitup = True 

while keepitup: 
    start_length = len(wordlist) 
    for word in wordlist: 
     if any(f in word for f in filters): 
      wordlist.remove(link) 
    end_length = len(wordlist) 
    if start_length != end_length: 
     keepitup = True 
    else: 
     keepitup = False 

這似乎荒謬。當然有更好的方法?

回答

4

你可以使用列表理解:

wordlist = [word for word in wordlist if all(f not in word for f in filters)] 

或過濾器功能:

filter(lambda word: all(f not in word for f in filters), wordlist) 

或者你可以遍歷單詞表的副本:

for word in wordlist[:]: 
    if any(f in word for f in filters): 
     wordlist.remove(word) 
+1

+1使用列表解析 – bruchowski 2014-10-04 04:45:35

+1

優雅,簡單,明確。我開始明白爲什麼人們從Python的列表理解能力中做出如此重大的貢獻。這太棒了。 – souldeux 2014-10-04 05:11:14

+1

@souldeux請注意,grc最後一個使用'remove()'的例子是通過'[:]'在'wordlist'的**副本**上工作的。嘗試在您正在迭代的列表上使用remove()會導致Bad Things™。我想我還應該提到他的列表理解示例正在創建一個全新的列表,並且在列表完全構建之前並不實際將其綁定到「wordlist」。IOW,'='左邊的'wordlist'是一個與右邊不同的新對象。 – 2014-10-04 14:17:23

相關問題