如何从 Python 字典中删除一个键?
- 2024-12-17 08:30:00
- admin 原创
- 150
问题描述:
如果存在键,我想从字典中删除该键。我目前使用以下代码:
if key in my_dict:
del my_dict[key]
如果没有该语句,则如果不存在该键,if
代码将引发。我该如何更简单地处理这个问题?KeyError
请参阅从字典中删除元素,了解从字典中删除键的问题的更多通用方法(包括生成修改副本的方法)。
解决方案 1:
要删除一个键而不管它是否在字典中,请使用双参数形式dict.pop()
:
my_dict.pop('key', None)
my_dict[key]
如果key
字典中存在则返回,None
否则返回。如果第二个参数未指定(即my_dict.pop('key')
)且不key
存在,KeyError
则引发 a。
要删除保证存在的键,您还可以使用
del my_dict['key']
KeyError
如果键不在字典中,则会出现一个错误。
解决方案 2:
具体来说,回答“是否有一行方法可以做到这一点?”
if 'key' in my_dict: del my_dict['key']
...好吧,你问了;-)
不过,您应该考虑到,这种从 中删除对象的方式dict
不是原子的—— 可能'key'
在语句my_dict
期间,但可能在执行if
之前被删除,在这种情况下将失败并出现。鉴于此,最安全的做法是使用或类似的东西del
`delKeyError
dict.pop`
try:
del my_dict['key']
except KeyError:
pass
当然,这绝对不是一句话的事。
解决方案 3:
我花了一些时间才弄清楚到底my_dict.pop("key", None)
在做什么。因此,我将添加此答案以节省其他人的谷歌搜索时间:
pop(key[, default])
如果key在字典中,则删除它并返回其值,否则返回default。如果没有给出default并且key不在字典中,
KeyError
则引发 a 。
文档
解决方案 4:
del my_dict[key]
`my_dict.pop(key)`比从字典中删除一个键(当键存在时)稍快一些
>>> import timeit
>>> setup = "d = {i: i for i in range(100000)}"
>>> timeit.timeit("del d[3]", setup=setup, number=1)
1.79e-06
>>> timeit.timeit("d.pop(3)", setup=setup, number=1)
2.09e-06
>>> timeit.timeit("d2 = {key: val for key, val in d.items() if key != 3}", setup=setup, number=1)
0.00786
但是当 key 不存在时,if key in my_dict: del my_dict[key]
比 稍快。两者都比/语句my_dict.pop(key, None)
快至少三倍:del
`try`except
>>> timeit.timeit("if 'missing key' in d: del d['missing key']", setup=setup)
0.0229
>>> timeit.timeit("d.pop('missing key', None)", setup=setup)
0.0426
>>> try_except = """
... try:
... del d['missing key']
... except KeyError:
... pass
... """
>>> timeit.timeit(try_except, setup=setup)
0.133
解决方案 5:
如果你需要在一行代码中从字典中删除很多键,我认为使用 map() 非常简洁并且具有 Pythonic 可读性:
myDict = {'a':1,'b':2,'c':3,'d':4}
map(myDict.pop, ['a','c']) # The list of keys to remove
>>> myDict
{'b': 2, 'd': 4}
如果需要捕获弹出字典中没有的值时的错误,请在 map() 中使用 lambda,如下所示:
map(lambda x: myDict.pop(x,None), ['a', 'c', 'e'])
[1, 3, None] # pop returns
>>> myDict
{'b': 2, 'd': 4}
或者在中python3
,您必须使用列表推导式:
[myDict.pop(x, None) for x in ['a', 'c', 'e']]
成功了。而且,尽管 myDict 没有“e”键,但“e”并没有导致错误。
解决方案 6:
您可以使用字典推导来创建一个删除该键的新字典:
>>> my_dict = {k: v for k, v in my_dict.items() if k != 'key'}
可以根据条件删除,key
不存在则不报错。
解决方案 7:
如果您想要非常详细,可以使用异常处理:
try:
del dict[key]
except KeyError: pass
pop()
但是,如果键不存在,则此方法比该方法慢。
my_dict.pop('key', None)
对于几个键来说这并不重要,但如果您要重复执行此操作,则后一种方法是更好的选择。
最快的方法是这样的:
if 'key' in dict:
del myDict['key']
但是这种方法很危险,因为如果'key'
在两行之间删除,KeyError
则会产生一个。
解决方案 8:
我们可以通过以下一些方法从 Python 字典中删除一个键。
使用del
关键字;它的方法几乎和你做的一样 -
myDict = {'one': 100, 'two': 200, 'three': 300 }
print(myDict) # {'one': 100, 'two': 200, 'three': 300}
if myDict.get('one') : del myDict['one']
print(myDict) # {'two': 200, 'three': 300}
或者
我们可以像下面这样做:
但需要注意的是,在此过程中,它实际上不会从字典中删除任何键,而是将特定键从该字典中排除。此外,我观察到它返回的字典的顺序与 不同myDict
。
myDict = {'one': 100, 'two': 200, 'three': 300, 'four': 400, 'five': 500}
{key:value for key, value in myDict.items() if key != 'one'}
如果我们在 shell 中运行它,它将执行类似这样的操作{'five': 500, 'four': 400, 'three': 300, 'two': 200}
- 请注意,它的顺序与 不同myDict
。同样,如果我们尝试打印myDict
,那么我们可以看到所有键,包括我们通过这种方法从字典中排除的键。但是,我们可以通过将以下语句赋值给变量来创建一个新字典:
var = {key:value for key, value in myDict.items() if key != 'one'}
现在如果我们尝试打印它,那么它将遵循父顺序:
print(var) # {'two': 200, 'three': 300, 'four': 400, 'five': 500}
或者
使用pop()
方法。
myDict = {'one': 100, 'two': 200, 'three': 300}
print(myDict)
if myDict.get('one') : myDict.pop('one')
print(myDict) # {'two': 200, 'three': 300}
del
和之间的区别pop
在于,使用pop()
方法,我们可以在需要时实际存储键的值,如下所示:
myDict = {'one': 100, 'two': 200, 'three': 300}
if myDict.get('one') : var = myDict.pop('one')
print(myDict) # {'two': 200, 'three': 300}
print(var) # 100
如果您发现这很有用,请分叉此要点以供将来参考。
解决方案 9:
我更喜欢不可变的版本
foo = {
1:1,
2:2,
3:3
}
removeKeys = [1,2]
def woKeys(dct, keyIter):
return {
k:v
for k,v in dct.items() if k not in keyIter
}
>>> print(woKeys(foo, removeKeys))
{3: 3}
>>> print(foo)
{1: 1, 2: 2, 3: 3}
解决方案 10:
另一种方法是使用 items() + 字典理解。
items() 与字典推导相结合也可以帮助我们实现键值对删除的任务,但它的缺点是它不是一种现成的字典技术。实际上,除了我们不想包含的键之外,还会创建一个新的字典。
test_dict = {"sai" : 22, "kiran" : 21, "vinod" : 21, "sangam" : 21}
# Printing dictionary before removal
print ("dictionary before performing remove is : " + str(test_dict))
# Using items() + dict comprehension to remove a dict. pair
# removes vinod
new_dict = {key:val for key, val in test_dict.items() if key != 'vinod'}
# Printing dictionary after removal
print ("dictionary after remove is : " + str(new_dict))
输出:
dictionary before performing remove is : {'sai': 22, 'kiran': 21, 'vinod': 21, 'sangam': 21}
dictionary after remove is : {'sai': 22, 'kiran': 21, 'sangam': 21}
解决方案 11:
移除多个键
Marc Maxmeister 的帖子讨论了这个问题,但这样做会创建一个不必要的(在我看来)列表。您只需使用 for 循环并丢弃弹出的值即可。
my_dict = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
lst = ['a', 'c', 'e']
for k in lst: my_dict.pop(k, None)
print(my_dict) # {'b': 2, 'd': 4}
或者如果您想使用map
,则使用最大长度为 0 的双端队列耗尽映射。
from collections import deque
from itertools import repeat
deque(map(my_dict.pop, ['a', 'c', 'e'], repeat(None)), 0)
print(my_dict) # {'b': 2, 'd': 4}
将字典拆分成两个
一种可能有用的情况dict.pop()
是,如果您想使用弹出的键值对创建一个新字典,则可以在一个 for 循环中有效地将字典分成两个。
new_dict = {k: v for k in lst if (v:=my_dict.pop(k, 'NULL')) != 'NULL'}
print(my_dict) # {'b': 2, 'd': 4}
print(new_dict) # {'a': 1, 'c': 3}