Remove an item from a dictionary when its key is unknown

PythonDictionary

Python Problem Overview


What is the best way to remove an item from a dictionary by value, i.e. when the item's key is unknown? 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?

Python Solutions


Solution 1 - Python

The dict.pop(key[, default]) method allows you to remove items when you know the key. It returns the value at the key if it removes the item otherwise it returns what is passed as default. See the docs.'

Example:

>>> dic = {'a':1, 'b':2}
>>> dic
{'a': 1, 'b': 2}
>>> dic.pop('c', 0)
0
>>> dic.pop('a', 0)
1
>>> dic
{'b': 2}

Solution 2 - Python

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.

Solution 3 - Python

a = {'name': 'your_name','class': 4}
if 'name' in a: del a['name']

Solution 4 - Python

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().

Solution 5 - Python

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]

Solution 6 - Python

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.

Solution 7 - Python

c is the new dictionary, and a is your original dictionary, {'z','w'} are the keys you want to remove from a

c = {key:a[key] for key in a.keys() - {'z', 'w'}}

Also check: https://www.safaribooksonline.com/library/view/python-cookbook-3rd/9781449357337/ch01.html

Solution 8 - Python

y={'username':'admin','machine':['a','b','c']}
if 'c' in y['machine'] : del y['machine'][y['machine'].index('c')]

Solution 9 - Python

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

Solution 10 - Python

This is how I would do it.

for key in some_dict.keys():
    if some_dict[key] == item_to_remove:
        some_dict.pop(key)
        break

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionButtons840View Question on Stackoverflow
Solution 1 - PythonN 1.1View Answer on Stackoverflow
Solution 2 - PythonTim PietzckerView Answer on Stackoverflow
Solution 3 - PythonKracekumarView Answer on Stackoverflow
Solution 4 - PythonLuu Tuan AnhView Answer on Stackoverflow
Solution 5 - Pythonuser97370View Answer on Stackoverflow
Solution 6 - PythonmithrandiView Answer on Stackoverflow
Solution 7 - Pythonpriya khokherView Answer on Stackoverflow
Solution 8 - Pythonuser3559640View Answer on Stackoverflow
Solution 9 - PythonThane AnthemView Answer on Stackoverflow
Solution 10 - PythonNathanView Answer on Stackoverflow