369

Is there any other way to delete an item in a dictionary only if the given key exists, other than:

if key in mydict:
    del mydict[key]

The scenario is that I'm given a collection of keys to be removed from a given dictionary, but I am not certain if all of them exist in the dictionary. Just in case I miss a more efficient solution.

Simon Hughes
  • 4,089
  • 4
  • 18
  • 12
  • 4
    @user1929959 Nope, that question wants a copy of the dictionary, and doesn't care about hte case that the key is not in the input. – phihag Mar 14 '13 at 13:52

3 Answers3

802

You can use dict.pop:

 mydict.pop("key", None)

Note that if the second argument, i.e. None is not given, KeyError is raised if the key is not in the dictionary. Providing the second argument prevents the conditional exception.

Asclepius
  • 49,954
  • 14
  • 144
  • 128
Adem Öztaş
  • 18,635
  • 4
  • 32
  • 41
22

There is also:

try:
    del mydict[key]
except KeyError:
    pass

This only does 1 lookup instead of 2. However, except clauses are expensive, so if you end up hitting the except clause frequently, this will probably be less efficient than what you already have.

mgilson
  • 283,004
  • 58
  • 591
  • 667
  • that is my fear. I wasn't sure about the cost of two look-ups per deletion vs. that of using try-except. – Simon Hughes Mar 14 '13 at 13:55
  • 4
    @SimonHughes -- See [this answer](http://programmers.stackexchange.com/questions/175655/python-forgiveness-vs-permission-and-duck-typing/175663#175663) on programmers ... – mgilson Mar 14 '13 at 13:57
  • 1
    This is called the [eaiser to ask for forgiveness than permission](https://docs.python.org/3/glossary.html#term-eafp) (EAFP) Python style. – akki Jul 22 '16 at 16:55
  • 1
    And EAFP is the recommended approach in Python. I would like to see the evidence and rationale for the statement "except clauses are expensive." – Bobort Oct 26 '16 at 14:44
  • 1
    @Bobort -- This has been a pretty well explained in a number of places. See [this answer](http://softwareengineering.stackexchange.com/questions/175655/python-forgiveness-vs-permission-and-duck-typing/175663#175663) on programmers or [this response](https://mail.python.org/pipermail/tutor/2011-January/081143.html) on the python mailing list. In short, setting up the try/except block is cheap, but handling the exception is less cheap. – mgilson Oct 26 '16 at 16:25
6

Approach: calculate keys to remove, mutate dict

Let's call keys the list/iterator of keys that you are given to remove. I'd do this:

keys_to_remove = set(keys).intersection(set(mydict.keys()))
for key in keys_to_remove:
    del mydict[key]

You calculate up front all the affected items and operate on them.

Approach: calculate keys to keep, make new dict with those keys

I prefer to create a new dictionary over mutating an existing one, so I would probably also consider this:

keys_to_keep = set(mydict.keys()) - set(keys)
new_dict = {k: v for k, v in mydict.iteritems() if k in keys_to_keep}

or:

keys_to_keep = set(mydict.keys()) - set(keys)
new_dict = {k: mydict[k] for k in keys_to_keep}
hughdbrown
  • 45,464
  • 20
  • 81
  • 105