我想知道是否有简单的方法按值从Python字典中删除一个或多个dictionary元素。

我们有一本叫myDict的字典:

1myDict = {1:"egg","Answer":42, 8:14,"foo":42}

并希望删除所有值等于42的项。

实施建议:

在myDict

中获取某个值的所有键的列表(参见字典中的get key by value)。

从myDict

(有关详细信息,请参阅从字典中删除元素)中删除此dict元素或元素(基于找到的键)。

那么,您认为在Python中实现这个问题的最优雅和最"Python式"的方法是什么?

想要"第一个…"mydict"中的值键有点可疑,@elegent,因为first的概念并不适用于字典。

@用户1656850:是的,你完全正确!非常感谢您指出这一点。我更新了问题:)

您可以使用简单的dict理解:

1myDict = {key:val for key, val in myDict.items() if val != 42}

像这样的:

1

2>>> {key:val for key, val in myDict.items() if val != 42}

{8: 14, 1: 'egg'}

我不会把它命名为item, key,而是将它命名为key, val,使用val != 42,因为它在语义上更正确。

谢谢你的回答!理解dict是个不错的主意,但我认为问题是如何从听写中删除条目。我知道我们只需要将理解的结果听写分配给myDict:myDict = {key:val for key, val in myDict.items() if val != 42},因此如果您方便,请更改您的答案。

@elegent已更改:)

必须创建一个要迭代的副本,因为在循环内更改字典的大小会导致RuntimeError。使用items()迭代字典中的键、值对,并将每个值与要查找的值进行比较。如果匹配,则从字典中删除键。

1

2

3for key, value in dict(myDict).items():

if value == 42:

del mydict[key]

在下面的评论中添加问题答案,因为它太大,无法发表评论。这里有一个简短的控制台会话,显示mydict.copy()和dict(myDict)完成了相同的事情。

>>>import copy
>>>dict1 = {1:"egg","Answer":42, 8:14,"foo":42}
>>>dict2 = dict(dict1)
>>>dict3 = dict1.copy()
>>>dict4 = dict1
>>>dict1[1] ="egg sandwich"
>>>dict1
{'Answer': 42, 1: 'egg sandwich', 'foo': 42, 8: 14}
>>>dict2
{'Answer': 42, 1: 'egg', 'foo': 42, 8: 14}
>>>dict3
{'Answer': 42, 1: 'egg', 'foo': 42, 8: 14}
>>>dict4
{'Answer': 42, 1: 'egg sandwich', 'foo': 42, 8: 14}
>>>dict2['foo'] ="I pity the"
dict1
>>>{'Answer': 42, 1: 'egg sandwich', 'foo': 42, 8: 14}
>>>dict2
{'Answer': 42, 1: 'egg', 'foo': 'I pity the', 8: 14}
>>>dict3
{'Answer': 42, 1: 'egg', 'foo': 42, 8: 14}
>>>dict4
{'Answer': 42, 1: 'egg sandwich', 'foo': 42, 8: 14}
>>>dict4[8] ="new"
>>>dict1
{'Answer': 42, 1: 'egg sandwich', 'foo': 42, 8: 'new'}
>>>dict2
{'Answer': 42, 1: 'egg', 'foo': 'I pity the', 8: 14}
>>>dict3
{'Answer': 42, 1: 'egg', 'foo': 42, 8: 14}
>>>dict4
{'Answer': 42, 1: 'egg sandwich', 'foo': 42, 8: 'new'}
`

myDict.copy()效率更高

我同意。谢谢你指出这一点。这也会起作用,并消除在循环之前创建副本的额外行:for key, value in dict(myDict).items():。

@克鲁恩:非常感谢你的回答!也许你可以根据你的命令编辑你的答案。

很高兴我能帮忙。我将编辑答案以反映更改。

@Padraiccunningham:myDict.copy()和dict(myDict)有什么区别?

他们都完成了同样的事情。他们创建了一个mydict的副本,而不是像myDictCopy = myDict那样只指向同一个字典的另一个名字。

请参阅上面编辑过的答案了解更多说明。

我喜欢使用"hit list"方法,在这里迭代字典,然后将要删除的内容添加到列表中,然后在迭代之后,从该列表中删除条目,如下所示:

HistList=对于dicentry:if测试条件,hitlist.append

进入Hitlist:删除dict[条目]

这只是一些伪代码,但我过去已经成功地使用了它

我也喜欢这种方法,因为不需要复制。它也适用于列表,只需存储索引,然后删除相应的元素,但首先从最高索引开始。

您可以迭代副本并进行查找:


3for k in myDict.copy():

if myDict[k] == 42:

del myDict[k]

或者只复制密钥:

myDict = {1:"egg","Answer":42, 8:14,"foo":42}
for k in list(myDict):
if myDict[k] == 42:
del myDict[k]
print(myDict)
{8: 14, 1: 'egg'}

如果你想改变原来的口述,它应该是最有效的。

谢谢!为什么要用reversed()来反转键列表?元素(即键和值对)不会在dict中排序,因此在我看来,更改顺序是不必要的步骤。

@Elegent,试着不倒车,你会看到

…这是有效的!:)顺便说一句,你不需要3个右括号…

@Elegent,是的,是个打字错误。是的,实际上列表(dict)适用于python2和3

好的,没问题,谢谢你的回答。我只是有点困惑。:)

使用字典理解。

如果需要复印件,请使用iteritems()。

1

2>>> {k:v for k, v in myDict.iteritems() if v!=42}

{8: 14, 1: 'egg'}

如果你不需要字典的副本,你可以使用viewitems()。

1

2>>> {k:v for k, v in myDict.viewitems() if v!=42}

{8: 14, 1: 'egg'}

请对投票结果发表评论,以便我改进我的回答。

谢谢!在python 3.x中,我们只使用.items(),而不使用.iteritems()和viewitems()?

是的,python 3.x和2.x之间存在差异,但是您的问题没有用python版本标记,所以我假设您正在寻找2.x解决方案。

是的,对不起你是对的。如果您方便的话,可以将这些额外的信息添加到您的答案中,这样我们就可以看到两个Python版本之间的区别。:)