如何从Python字典中删除密钥?

Ton*_*ony 1539 python dictionary unset data-structures

当我试图从字典中删除一个键时,我写道:

if 'key' in myDict:
    del myDict['key']
Run Code Online (Sandbox Code Playgroud)

有这样一种方式吗?

Sve*_*ach 2515

用途dict.pop():

my_dict.pop('key', None)
Run Code Online (Sandbox Code Playgroud)

my_dict[key]如果key字典中存在,则返回,None否则返回.如果未指定第二个参数(即.my_dict.pop('key'))key且不存在,KeyError则引发a.

  • 有时使用`pop()`而不是`del`的优点:它返回该键的值.这样,您就可以在一行代码中从dict获取和删除条目. (127认同)
  • @SalvatoreCosentino不,忽略函数的返回值根本不是低效的.恰恰相反 - 如果密钥不存在,这个解决方案比`try` /`except`解决方案要快得多.您可能会发现其中一个或另一个更容易阅读,这很好.两者都是惯用的Python,所以选择你喜欢的任何东西.但声称这个答案更复杂或效率更低是没有意义的. (25认同)
  • @SalvatoreCosentino我不能跟随你的论点.这个答案中的代码比其他答案中的代码更复杂? (8认同)
  • 在问题中,不需要保留该值.这只会增加不必要的复杂性.@zigg(下面)的答案要好得多. (6认同)
  • @ user5359531我不明白.这怎么回事?Python的内置类型中的所有方法都没有返回"self",所以如果这个方法做到了,那就太令人惊讶了. (3认同)
  • @ user5359531您通常应避免具有副作用的列表理解,因为它们令人困惑。如果dict.pop()返回原始字典,则b = [a.d中d的d.pop(“ key”))将修改_both_列表,a和b,因为它们都共享相同的字典对象。这就是Python约定变异方法没有返回值的约定的部分原因。(事实上​​,dict.pop()是该约定的一个例外,但并不违反约定的精神。) (3认同)
  • @ user5359531如果你想改变一个字典列表,可以使用for循环:`for d in a:d.pop("key",None)`.如果你想保持原始词典不变,首先复制它们:`b = [d.copy()for d in a]`. (3认同)
  • 您好@SvenMarnach,对1)我认为以下答案更为优雅(例如,处理异常)2)在大多数编程语言(和数据结构)中使用'pop'表示您要存储已删除的值,并且该问题仅询问有关删除密钥的问题。返回一个从未使用过的值将是毫无效率的。 (2认同)

zig*_*igg 336

特别回答"有这样一种方式吗?"

if 'key' in myDict: del myDict['key']
Run Code Online (Sandbox Code Playgroud)

......好吧,你 ;-)

你应该考虑,虽然,从删除对象的这种方式dict不是原子 -它是可能的,'key'可能是在myDict该过程中if的语句,但是可以删除之前del被执行,在这种情况下del将失败,KeyError.鉴于此,无论是使用dict.pop还是其他方面都是最安全的

try:
    del myDict['key']
except KeyError:
    pass
Run Code Online (Sandbox Code Playgroud)

当然,这绝对不是一个单行.

  • 是的,'pop`绝对是更简洁的,尽管这样做有一个关键优势:它立即清楚它正在做什么. (23认同)
  • @ChrisBarker我发现如果密钥存在,'try`稍微快一些,但如果没有,'try`的确比较慢.`pop`是相当一致的,但比使用非现有键的`try`更慢.请参阅https://gist.github.com/zigg/6280653.最终,它取决于你期望密钥实际出现在字典中的频率,以及你是否需要原子性 - 当然,你是否需要过早优化;) (15认同)
  • 我认为不应忽视清晰的价值.+1为此. (7认同)
  • `try/except`语句更昂贵.提出异常很慢. (3认同)
  • 关于 try/except 的费用,您还可以在 mydict 中使用 ```if 'key': #then del...```。我需要从字典中取出一个键/值来正确解析,pop 不是一个完美的解决方案。 (3认同)

Aka*_*all 136

我花了一些时间来弄清楚到底my_dict.pop("key", None)在做什么.所以我将这个作为一个答案,以节省其他人的谷歌搜索时间:

pop(key [,default])

如果key在字典中,则将其删除并返回其值,否则返回default.如果未给出default并且key不在字典中,则引发KeyError

文档

  • 只需在python解释器中输入help(dict.pop)即可. (11认同)
  • 当你需要知道什么是什么时,help()和dir()可以成为你的朋友. (11认同)
  • 此外,接受的答案有一个指向文档的链接(带有函数的锚点). (5认同)
  • 或者在IPython中的`dict.pop?`. (2认同)

Pet*_*mit 45

上述三种解决方案的时间安排.

小字典:

>>> import timeit
>>> timeit.timeit("d={'a':1}; d.pop('a')")
0.23399464370632472
>>> timeit.timeit("d={'a':1}; del d['a']")
0.15225347193388927
>>> timeit.timeit("d={'a':1}; d2 = {key: val for key, val in d.items() if key != 'a'}")
0.5365207354998063
Run Code Online (Sandbox Code Playgroud)

较大的字典:

>>> timeit.timeit("d={nr: nr for nr in range(100)}; d.pop(3)")
5.478138627299643
>>> timeit.timeit("d={nr: nr for nr in range(100)}; del d[3]")
5.362219126590048
>>> timeit.timeit("d={nr: nr for nr in range(100)}; d2 = {key: val for key, val in d.items() if key != 3}")
13.93129749387532
Run Code Online (Sandbox Code Playgroud)

  • 通常人们会写一个"结论",而不仅仅是倾销一些基准. (30认同)
  • 我将把它包装成user1767754:del ist是从Python字典中删除密钥的最快方法 (6认同)
  • @Boris - 这作为一般练习很有用。 (4认同)
  • @daisy 我想说的是,你应该选择最易读的语法,而不是快 300 纳秒的操作(这实际上是上面第一组计时中“del”和“pop”之间的区别) (3认同)

Mar*_*ter 40

如果你需要在一行代码中从字典中删除很多键,我认为使用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}
Run Code Online (Sandbox Code Playgroud)

如果您需要在弹出不在字典中的值的地方捕获错误,请在map()中使用lambda,如下所示:

map(lambda x: myDict.pop(x,None), ['a', 'c', 'e'])
[1, 3, None] # pop returns
>>> myDict
{'b': 2, 'd': 4}
Run Code Online (Sandbox Code Playgroud)

有用.即使myDict没有'e'键,'e'也不会导致错误.

  • 这在Python 3中不起作用,因为`map`和朋友现在很懒并返回迭代器.使用`map`进行副作用通常被认为是不良做法; 一个标准`for ... in`循环会更好.有关详细信息,请参阅[视图和迭代器而不是列表](https://docs.python.org/3.0/whatsnew/3.0.html#views-and-iterators-instead-of-lists). (38认同)
  • 无论品味和实践风格如何,列表推导仍然应该在Py3` [myDict.pop(i,None)for my in ['a','c']]`中工作,因为它们提供了`map`的一般替代方案(和`过滤器`). (5认同)

Sha*_*eem 16

使用:

>>> if myDict.get(key): myDict.pop(key)
Run Code Online (Sandbox Code Playgroud)

其他方式:

>>> {k:v for k, v in myDict.items() if k != 'key'}
Run Code Online (Sandbox Code Playgroud)

您可以按条件删除.如果key不存在则没有错误.

  • 这个答案与其他答案不同,因为它没有副作用(它不会改变原始字典)。 (7认同)
  • 在Python 3中删除了`dict.has_key`,而应该使用`in`(myDict`中的`键).您也应该在Python 2中执行此操作. (3认同)
  • 第一个是完全错误的(如果键映射为“ None”,一个空字符串或一个零,它将不会被删除),第二个则效率非常低。 (2认同)
  • 虽然这可能也是我会这样做的方式,但这会在内存中创建一个全新的字典,将对象复制(引用)到新字典中。然后将其保存为旧名称。对于大型词典,这可能需要一些时间。在所有情况下,“del dict[key]”或“dict.pop(key)”都会更快。 (2认同)

Sar*_*pta 14

使用"del"关键字:

del dict[key]
Run Code Online (Sandbox Code Playgroud)


M.I*_*nat 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}
Run Code Online (Sandbox Code Playgroud)

要么

我们可以这样做:

但是应该记住,在这个过程中实际上它不会从字典中删除任何键,而不是从该字典中排除特定键.另外,我观察到它返回了一个字典,它没有被命令相同myDict.

myDict = {'one': 100, 'two': 200, 'three': 300, 'four': 400, 'five': 500}
{key:value for key, value in myDict.items() if key != 'one'}
Run Code Online (Sandbox Code Playgroud)

如果我们在shell中运行它,它将执行类似的操作{'five': 500, 'four': 400, 'three': 300, 'two': 200}- 注意它与它的顺序不同myDict.再次,如果我们尝试打印myDict,那么我们可以看到所有键,包括我们通过这种方法排除在字典中.但是,我们可以通过将以下语句分配给变量来创建新字典:

var = {key:value for key, value in myDict.items() if key != 'one'}
Run Code Online (Sandbox Code Playgroud)

现在,如果我们尝试打印它,那么它将遵循父订单:

print(var) # {'two': 200, 'three': 300, 'four': 400, 'five': 500}
Run Code Online (Sandbox Code Playgroud)

要么

使用pop()方法.

myDict = {'one': 100, 'two': 200, 'three': 300}
print(myDict)

if myDict.get('one') : myDict.pop('one')
print(myDict)  # {'two': 200, 'three': 300}
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

这个要点以供将来参考,如果你发现这很有用.

  • 不要使用 `if myDict.get('one')` 来检查密钥是否存在!如果 myDict['one'] 有一个 falsey 值,它就会失败。此外,dicts 没有固有的顺序,因此提及它没有意义。 (6认同)

Ale*_*ine 8

如果您想非常冗长,可以使用异常处理:

try: 
    del dict[key]

except KeyError: pass
Run Code Online (Sandbox Code Playgroud)

但是,pop()如果密钥不存在,这比方法慢。

my_dict.pop('key', None)
Run Code Online (Sandbox Code Playgroud)

几个键无关紧要,但如果您重复执行此操作,则后一种方法是更好的选择。

最快的方法是这样的:

if 'key' in dict: 
    del myDict['key']
Run Code Online (Sandbox Code Playgroud)

但是这种方法是危险的,因为如果'key'在两行之间删除,aKeyError将被提出。


Cer*_*vEd 7

我更喜欢不可变的版本

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}
Run Code Online (Sandbox Code Playgroud)


小智 6

另一种方法是使用 items() + dict 理解。

\n

items() 与 dict 理解相结合也可以帮助我们实现键值对删除的任务,但它的缺点是不是就地 dict 技术。实际上,如果创建了一个新的字典,除了我们不希望包含的键\xe2\x80\x99。

\n
test_dict = {"sai" : 22, "kiran" : 21, "vinod" : 21, "sangam" : 21}\n\n# Printing dictionary before removal\nprint ("dictionary before performing remove is : " + str(test_dict))\n\n# Using items() + dict comprehension to remove a dict. pair\n# removes  vinod\nnew_dict = {key:val for key, val in test_dict.items() if key != 'vinod'}\n\n# Printing dictionary after removal\nprint ("dictionary after remove is : " + str(new_dict))\n
Run Code Online (Sandbox Code Playgroud)\n

输出:

\n
dictionary before performing remove is : {'sai': 22, 'kiran': 21, 'vinod': 21, 'sangam': 21}\ndictionary after remove is : {'sai': 22, 'kiran': 21, 'sangam': 21}\n
Run Code Online (Sandbox Code Playgroud)\n


Ans*_*ngh 5

字典数据类型有一个被调用的方法dict_name.pop(item),它可以用来从字典中删除一个键:值对。

a={9:4,2:3,4:2,1:3}
a.pop(9)
print(a)
Run Code Online (Sandbox Code Playgroud)

这将使输出为:

{2: 3, 4: 2, 1: 3}
Run Code Online (Sandbox Code Playgroud)

通过这种方式,您可以在一行中从字典中删除一个项目。