3

I was wondering if there is a pythonic way to delete an item completely from a dictionary. To illustrate that, consider the dict given below:

mydict = {'A': ['B', 'O'],
          'B': ['A'],
          'C': ['D', 'E', 'F', 'O'],
          'D': ['E', 'C', 'F'],
          'E': ['C', 'D', 'F', 'O'],
          'F': ['C', 'D', 'E'],
          'G': ['H', 'O'],
          'H': ['G', 'O'],
          'O': ['A', 'C', 'E', 'G', 'H']}

And let's say, I want to remove 'E' from the dictionary. Then I expect to get such a dictionary:

mydict = {'A': ['B', 'O'],
          'B': ['A'],
          'C': ['D', 'F', 'O'],
          'D': ['C', 'F'],
          'F': ['C', 'D', ],
          'G': ['H', 'O'],
          'H': ['G', 'O'],
          'O': ['A', 'C', 'G', 'H']}

Of course, I can get it by looping over its keys and values. But, I am wondering if there is a better way to do that.

3
  • @tobias_k: the values also need cleaning. Commented Jul 22, 2014 at 11:21
  • @MartijnPieters Ah, thanks for pointing out. Totally missed that part! Commented Jul 22, 2014 at 11:21
  • 2
    Just a meta-comment: an 'E' that appears as a key is a completely different beast from an 'E' that appears as an entry in a list that is a value. So it shouldn't be surprising that there's no unified way to handle both cases. Commented Jul 22, 2014 at 11:33

2 Answers 2

8

No, there are no other options here than a full set of loops, as you need to remove any 'E' strings from your values:

{k: [i for i in v if i != 'E'] for k, v in mydict.iteritems() if k != 'E'}

This rebuilds your dictionary, removing the 'E' key while we are at it, leaving you with a new dictionary that is entirely 'E'-less.

If you want anything more efficient, you'll need to add more information. An index of positions for example:

from collections import defaultdict

reverse_node_map = defaultdict(set)
for k, nodes in mydict.iteritems():
    for node in nodes:
        reverse_node_map[node].add(k)

and then use reverse_node_map to pinpoint what lists to update when you want to delete a node. You'd have to keep the index up-to-date with any mutations, of course.

You should also consider replacing the list values with sets if order isn't important and the nodes are unique. Removing elements from sets is a lot more efficient and would only requiring looping over all the values of mydict, forgoing the nested loop over the elements of the lists. Combined with the reverse index, you can then delete nodes much more efficiently.

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

1 Comment

OK, I thought there may be a magic command that I don't know. Thanks for your comments and answer.
0

I don't think there's a simple line answer in python. Maybe you can try:

  mydict.pop('E', None) 

This will remove the keys with 'E' from dictionary. Now for removing 'E' values:

for key in mydict.keys(): 
    mydict[key].remove('E')

Further reference for this methods can be found on: Python Docs

Hope it helps!

2 Comments

There is no use in popping the key from the dictionary, then set it back again; just mydict[key].remove('E') would do.
I can do nothing but agree!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.