从Python对象中删除不在列表中的键?

21

我有这些钥匙:

keep = ["a","c"]

我的字典:

testdict = {'
'a':'vala',
'b':'valb',
'c':'valc',
'd':'vald'
}

期望的输出:

testdict = {
'a':'vala',
'c':'valc'
}
我想移除所有不在列表中的键。最快的方法是什么?
我尝试过:
for key, value in testdict.iteritems():
      if key not in keep:
         del testdict[key]

但是由于大小在改变,以上内容会出现错误。


keep 可以变得多大? - Simeon Visser
保持可能只有4或5个键。 - Setsuna
1
如果keep包含了testDict中不存在的键,会怎么样? - Joran Beasley
这可能会对你有所帮助:安全地从字典中删除多个键 - Jose Ricardo Bustos M.
3个回答

35

不要删除原有的内容,而是构建一个新的字典:

newdict = {k: testdict[k] for k in keep}

如果keep可能包含在testdict中不存在的键,则添加相应条件:

newdict = {k: testdict[k] for k in keep if k in testdict}

如果您确实必须修改字典对象,请记住在遍历字典时不能修改它。因此,先遍历再删除:

to_delete = set(testdict.keys()).difference(keep)
for d in to_delete:
    del testdict[d]

1
如果testdict中没有k,则会出现KeyError。使用newdict = {k: testdict[k] for k in keep if k in testdict}是否更好? - msw
或者可能是 {k: testdict.get(k, None) for k in keep} - Adam Smith
总的来说,如果 keep 无效,我通常会希望产生一个异常,而不是后来发现 "无效" 的字典并猜测它们来自哪里。但这取决于具体的用例。我已经修改了答案。 - phihag
@phihag 我同意,根据 OP 中提供的信息还不足以选择两者之间。无论如何,这是一个优雅的答案。 - msw
testdict = {k: testdict[k] for k in keep if k in testdict},不管上面有多好的答案! - Robert Nagtegaal

3
print({k:testDict[k] for k in keep})

或者在py<2.7中

print dict((k,testDict[k]) for k in keep)

这些假设保证了在testDict中存在中的每个键。

字典推导式在Python 2.7中可用!无论如何,为什么要构建一个列表,然后将其馈入dict,而不是使用生成器表达式呢? - phihag

2
问题在于您在使用迭代器时改变了键名。如果您有一个正确的键名列表,就可以避免这个问题。
for key in list(testdict.keys()):
      if key not in keep:
         del testdict[key]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接