Python dict del

7 篇文章 0 订阅
2 篇文章 0 订阅

What is the best way to remove an item from a dictionary? Here's a simple approach:

for key, item in some_dict.items():
    if item is item_to_remove:
        del some_dict[key]

Are there better ways? Is there anything wrong with mutating (deleting items) from the dictionary while iterating it?

share improve this question
 
 
The underline reason for prohibiting mutating dict while iterating it is because internally there is an order for iteration, if you mutate the keys, the order would be undermined, which results unknown behavior. –  ShadowGiraffe  Jul 26 '15 at 19:21 

9 Answers

up vote 52 down vote accepted

Be aware that you're currently testing for object identity (is only returns True if both operands are represented by the same object in memory - this is not always the case with two object that compare equal with ==). If you are doing this on purpose, then you could rewrite your code as

some_dict = {key: value for key, value in some_dict.items() 
             if value is not value_to_remove}

But this may not do what you want:

>>> some_dict = {1: "Hello", 2: "Goodbye", 3: "You say yes", 4: "I say no"}
>>> value_to_remove = "You say yes"
>>> some_dict = {key: value for key, value in some_dict.items() if value is not value_to_remove}
>>> some_dict
{1: 'Hello', 2: 'Goodbye', 3: 'You say yes', 4: 'I say no'}
>>> some_dict = {key: value for key, value in some_dict.items() if value != value_to_remove}
>>> some_dict
{1: 'Hello', 2: 'Goodbye', 4: 'I say no'}

So you probably want != instead of is not.

share improve this answer
 
2 
Is that a dictionary compression? When were they added? –  Buttons840  Mar 27 '11 at 5:52
3 
you could use some_dict.iteritems() here and put for and if statements on separate lines for readability –  J.F. Sebastian  Mar 27 '11 at 5:57
3 
I believe dictionary comprehensions were added in Python 2.7. –  mithrandi  Mar 27 '11 at 5:58
2 
@J.F. Sebastian: I'm on Python 3, and iteritems is now items. In Python 2.7, iteritems() is indeed better. –  Tim Pietzcker  Mar 27 '11 at 6:00
 
@Buttons840 they are called dict comprehensions in PEP 274 or dictionary displays. as the PEP says they were added in 2.7 as backported 3.x feats. alternatively you can feed dict() with an appropriate generator expression, which is 2.4. meta: can browse the peps here for finding stuff out. –  n611x007  May 29 '14 at 11:43
>>> dic = {'a':1, 'b':2}
>>> dic
{'a': 1, 'b': 2}
>>> dic.pop('c', 0)
0
>>> dic.pop('a', 0)
1
>>> dic
{'b': 2}
share improve this answer
 
a = {'name': 'your_name','class': 4}
if 'name' in a: del a['name']
share improve this answer
 

A simple comparison between del and pop():

import timeit
code = """
results = {'A': 1, 'B': 2, 'C': 3}
del results['A']
del results['B']
"""
print timeit.timeit(code, number=100000)
code = """
results = {'A': 1, 'B': 2, 'C': 3}
results.pop('A')
results.pop('B')
"""
print timeit.timeit(code, number=100000)

result: 

0.0329667857143
0.0451040902256

So, del is faster than pop()

share improve this answer
 
5 
However, the performance difference is not great, and if you want to avoid raising an exception, you can provide a second argument to pop() (as @n-1-1 does above) - which is not an option for the deloperator. –  Alex Dupuy  Jul 11 '14 at 7:46
 
Ancillary to the question, but I'd also been struggling to understand timeit. Thank you for this clear example. –  Adam_G  May 1 '15 at 1:02

items() returns a list, and it is that list you are iterating, so mutating the dict in the loop doesn't matter here. If you were using iteritems() instead, mutating the dict in the loop would be problematic, and likewise for viewitems() in Python 2.7.

I can't think of a better way to remove items from a dict by value.

share improve this answer
 

I'd build a list of keys that need removing, then remove them. It's simple, efficient and avoids any problem about simultaneously iterating over and mutating the dict.

keys_to_remove = [key for key, value in some_dict.iteritems()
                  if value == value_to_remove]
for key in keys_to_remove:
    del some_dict[key]
share improve this answer
 

There is nothing wrong with deleting items from the dictionary while iterating, as you've proposed. Be careful about multiple threads using the same dictionary at the same time, which may result in a KeyError or other problems.

Of course, see the docs at http://docs.python.org/library/stdtypes.html#typesmapping


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值