477

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.

1
  • 5
    @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. Commented Mar 14, 2013 at 13:52

3 Answers 3

1004

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.

Sign up to request clarification or add additional context in comments.

7 Comments

For reference, the second argument to .pop() is what it returns if the key is not found.
Does this only do 1 lookup?
So, just for curiosity, what is the default value of the second argument in the source code?
@CarlosPinzón There isn't one. See the docs. D.pop(key[, default]) "If key is not found, default is returned if given, otherwise KeyError is raised".
@GirishGupta: I doubt it. Python dict is written in C. I would be very surprised if not optimised for single lookup. Ref: github.com/python/cpython/blob/main/Objects/dictobject.c#L2206
|
31

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.

5 Comments

that is my fear. I wasn't sure about the cost of two look-ups per deletion vs. that of using try-except.
@SimonHughes -- See this answer on programmers ...
This is called the eaiser to ask for forgiveness than permission (EAFP) Python style.
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 -- This has been a pretty well explained in a number of places. See this answer on programmers or this response on the python mailing list. In short, setting up the try/except block is cheap, but handling the exception is less cheap.
7

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}

1 Comment

first approach doesn't look thread-safe to me

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.