2011-08-22 29 views
5
from collections import * 
ignore = ['the','a','if','in','it','of','or'] 
ArtofWarCounter = Counter(ArtofWarLIST) 
for word in ArtofWarCounter: 
    if word in ignore: 
     del ArtofWarCounter[word] 

ArtofWarCounter是一個Counter對象,包含了戰爭藝術中的所有單詞。我試圖從ArtofWarCounter中刪除ignore中的文字。如何在沒有調用RuntimeError的情況下使用循環刪除Counter對象中的條目?

回溯:

File "<pyshell#10>", line 1, in <module> 
    for word in ArtofWarCounter: 
RuntimeError: dictionary changed size during iteration 

回答

6

對於最少的代碼更改,請使用list,讓你遍歷對象從Counter

ignore = ['the','a','if','in','it','of','or'] 
ArtofWarCounter = Counter(ArtofWarLIST) 
for word in list(ArtofWarCounter): 
    if word in ignore: 
     del ArtofWarCounter[word] 

在Python2解耦,你可以使用ArtofWarCounter.keys()代替list(ArtofWarCounter),但是當它是如此簡單編寫面向未來的代碼,爲什麼不這樣做?

這是一個更好的主意,只是沒有指望你希望忽略

ignore = {'the','a','if','in','it','of','or'} 
ArtofWarCounter = Counter(x for x in ArtofWarLIST if x not in ignore) 

注意,我做了ignoreset這使得測試x not in ignore更有效

+0

很好的答案,謝謝。我使用了一個小小的變體:而不是列表中的單詞(ArtofWarCounter),我使用ArtofWarLIST,因爲它們本質上是相同的。謝謝! – Louis93

+0

@ Louis93,我認爲'ArtofWarLIST'可以包含重複項,這意味着您將循環多餘的時間。我會添加一個更好的方式來回答我的回答 –

1

說明爲何當前的方法是行不通的以下問題:
Remove items from a list while iterating

基本上你不應該添加或當你在遍歷它從一個集合中刪除項目。 collections.Counterdict一個子類,請參閱文檔中的以下警告爲dict.iteritems()

Using iteritems() while adding or deleting entries in the dictionary may raise a RuntimeError or fail to iterate over all entries.

+0

不,跑到一個錯誤。 ArtofWarCounter [:] = [在WordofWarCounter中的單詞如果單詞不在忽略] TypeError:難以置信的類型 另外Counters是一個字典子類,所以我懷疑他們可以像列表一樣切片,除非我誤會了 – Louis93

+0

@ Louis93 - 對不起,我的迴應有點倉促。我留下了解釋,因爲它可能仍然有用,其他答案之一應該給你一個工作的解決方案。 –

-1

使用計數器,向後遍歷循環(後到前),根據需要進行刪除。循環直到零。

+0

我不確定我是否明白,爲什麼這樣做會始終如一地執行? – Louis93

+0

我很抱歉,我對Python不是很熟悉 - 但我已經在C#中用這種方法處理了這個「Collection modified」問題。我需要使用計數器來循環收集 - 但是,我無法從0到(n - 1)啓動計數器。這是因爲,如果我試圖循環到(n - 1),我實際上會刪除0到(n - 1)之間的某些值,所以循環的結束條件將失敗。遍歷循環後字將在這種情況下工作,因爲,我的循環結束條件(即0)將始終有效。另外,因爲我從(n - 1)開始作爲我的循環開始條件,所以我不會錯過任何。 – Arun

+0

謝謝Louis93投票(兩次),當時我只是想幫助你! – Arun

11

不要循環項目在字典的所有單詞中找到一個條目,字典在查找方面要好得多。

您遍歷所有的ignore列表,刪除存在的條目:

ignore = ['the','a','if','in','it','of','or'] 
for word in ignore: 
    if word in ArtofWarCounter: 
     del ArtofWarCounter[word] 
+0

應該是被接受的答案。 – Forethinker

相關問題