82

I have a python dict and I'd like to silently remove either None and '' keys from my dictionary so I came up with something like this:

try:
    del my_dict[None]
except KeyError:
    pass

try:
    del my_dict['']
except KeyError:
   pass

As you see, it is less readable and it causes me to write duplicate code. So I want to know if there is a method in python to remove any key from a dict without throwing a key error?

Roshin Raphel
  • 2,612
  • 4
  • 22
  • 40
Ozgur Vatansever
  • 49,246
  • 17
  • 84
  • 119

4 Answers4

148

You can do this:

d.pop("", None)
d.pop(None, None)

Pops dictionary with a default value that you ignore.

Keith
  • 42,110
  • 11
  • 57
  • 76
15

You could use the dict.pop method and ignore the result:

for key in [None, '']:
    d.pop(key, None)
Jon Clements
  • 138,671
  • 33
  • 247
  • 280
3

The following will delete the keys, if they are present, and it won't throw an error:

for d in [None, '']:
    if d in my_dict:
        del my_dict[d]
Ozgur Vatansever
  • 49,246
  • 17
  • 84
  • 119
Simeon Visser
  • 118,920
  • 18
  • 185
  • 180
  • @ozgurv Dictionary lookup is not O(n), it is O(1) – jamylak Jul 06 '12 at 08:23
  • @ozgurv: checking whether a key is in a dict is O(1), as is deleting a key from a dict. It *does* however cause you to do two lookups rather than one. – Ben Jul 06 '12 at 08:25
  • @ozgurv no, it's not. Check out the Python docs on [time complexity](http://wiki.python.org/moin/TimeComplexity) for data structures. You aren't looking for keys that end up in the amortized case there either. – Jeff Tratner Jul 06 '12 at 08:25
  • Thank you I was not aware of that. I thought sth like: if d in my_sexy_dict.keys(). Because .keys() returns a list and I consider as searching an element in a list. – Ozgur Vatansever Jul 06 '12 at 08:25
  • @ozgurv `my_sexy_dict.keys()` is not O(1), because it generates a list first (or in Python a "view"). `k in my_sexy_dict` is O(1) – Jeff Tratner Jul 06 '12 at 08:27
  • 1
    @ozgurv In Python 3 `dict.keys` no longer returns a list so they are practically the same, as they should be. – jamylak Jul 06 '12 at 08:32
  • 2
    @jamylak you're definitely right, I never understood why it returns a list instead of a set. – Ozgur Vatansever Jul 06 '12 at 08:34
  • I think it returns a list so that if you iterate over `keys()` and `values()` you get the key-value pairs. (I know, why would you do this intead of using `items()`? I don't know.) If you want a set of the keys in dict `dd`, you can just use `set(dd)` - the default iterator over a dict is to iterate over its keys. – PaulMcG Jul 06 '12 at 08:57
3

You can try:

d = dict((k, v) for k,v in d.items() if k is not None and k != '')

or to remove all empty-like keys

d = dict((k, v) for k,v in d.items() if k )
Maksym Polshcha
  • 18,030
  • 8
  • 52
  • 77
  • No need for `[`, `]`. You are creating an unnecessary intermediary list comprehension. If you remove them, the more efficient generator will be used. – jamylak Jul 06 '12 at 08:28