Python 如何在不调用RuntimeError的情况下删除带有循环的计数器对象中的条目?

Python 如何在不调用RuntimeError的情况下删除带有循环的计数器对象中的条目?,python,collections,containers,counter,Python,Collections,Containers,Counter,ArtofWarCounter是包含《孙子兵法》中所有词语的反对象。我正试图从ArtofWarCounter中删除ignore中的单词 回溯: from collections import * ignore = ['the','a','if','in','it','of','or'] ArtofWarCounter = Counter(ArtofWarLIST) for word in ArtofWarCounter: if word in ignore: del Ar

ArtofWarCounter是包含《孙子兵法》中所有词语的反对象。我正试图从ArtofWarCounter中删除
ignore
中的单词

回溯:

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]
文件“”,第1行,在
对于ArtofWarCounter中的单词:
RuntimeError:字典在迭代期间更改了大小

有关当前方法不起作用的原因,请参见以下问题:

基本上,在集合上循环时,不应该添加或删除集合中的项<代码>集合。计数器是dict的子类,请参见文档中的以下警告:

在字典中添加或删除条目时使用
iteritems()


使用计数器,向后(从最后到第一)遍历循环,根据需要移除。循环到零。

对于最小的代码更改,请使用
列表
,以便您迭代的对象与
计数器

  File "<pyshell#10>", line 1, in <module>
    for word in ArtofWarCounter:
RuntimeError: dictionary changed size during iteration
在Python2中,您可以使用
ArtOfWaCounter.keys()
而不是
list(ArtOfWaCounter)
,但是当编写面向未来的代码如此简单时,为什么不这样做呢

最好不要计算你想忽略的项目

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

请注意,我将
ignore
设置为
set
,这使得测试
x不在ignore
中更加有效

不要在dict的所有单词上循环以查找条目,dict在查找时会更好

忽略
列表上循环,并删除存在的条目:

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

不,运行到一个错误。ArtofWarCounter[:]=[ArtofWarCounter中的字对字如果字不在忽略中]类型错误:不可损坏类型计数器也是dict子类,所以我怀疑它们是否可以像列表一样切片,除非我是mistaken@Louis93-对不起,我的回答有点仓促。我留下了解释,因为它可能仍然有用,其他答案中的一个应该会给你一个有效的解决方案。我不确定我是否理解它,为什么这项工作会从头到尾重复进行呢?很抱歉,我对Python不是很熟悉,但我已经用C#这种方式处理了这个“集合修改”问题。我需要使用计数器在集合中循环-但是,我无法将计数器从0启动到(n-1)。这是因为,如果我尝试循环到(n-1),我的循环结束条件将失败,那时我实际上已经删除了0到(n-1)之间的一些。在这种情况下,遍历循环backwords将有效,因为我的循环结束条件(即0)将始终有效。另外,因为我以(n-1)作为循环开始条件,所以我不会错过任何一个条件。感谢Louis93在我只是想帮你的时候否决了它(两次)!OP不太可能因为两次投票的失败而受到指责,更不用说两次了。无论如何,你只能对某件事投一次反对票。答案是被否决,因为它行不通。正在修改的容器是无序的,因此不能像使用C#中的
字典
那样使用索引值对其进行反向迭代。此外,以这种方式进行迭代通常被认为是非常不符合Python的。即使C++程序员现在也避免了:比如我的答案。我不把它当作一个经验法则来否决。如果答案似乎没有帮助,我就不赞成。谢谢你的帮助,但是你的方法并没有很好地翻译成Python,正如Karl提到的,非常好的回答,谢谢。我使用了一个小小的变体:我没有使用列表中的单词(ArtofWarCounter),而是使用了ArtofWarLIST,因为它们本质上是相同的东西。谢谢@Louis93,我认为
ArtofWarLIST
可能包含重复项,这意味着您将循环额外的时间。我会给我的答案加一个更好的方法
ignore = ['the','a','if','in','it','of','or']
for word in ignore:
    if word in ArtofWarCounter:
        del ArtofWarCounter[word]