Reputation: 7924
I have a dictionary as:
default = {'a': ['alpha'], 'b': ['beta','gamma'], 'g': []}
I wish to eliminate the empty values as:
default = {'a': ['alpha'], 'b': ['beta','gamma']}
I wrote a function (following an example found on the web)
def remove_empty_keys(d):
for k in d.keys():
try:
if len(d[k]) < 1:
del[k]
except:
pass
return(d)
I have the following questions:
1- I didn't find the mistake why it always returns following -
remove_empty_keys(default)
{'a': ['alpha'], 'b': ['beta'], 'g': []}
2- Is there a built-in function to eliminate/delete Null/None/empty values from Python dictionary without creating a copy of the original dictionary?
Upvotes: 12
Views: 14992
Reputation: 8298
If the values are all lists, so you can use their truth's, you could use itertools.compress
:
from itertools import compress
d = {'a': ['alpha'], 'b': ['beta','gamma'], 'g': []}
new_d = dict(compress(d.items(), d.values()))
print(new_d) # {'a': ['alpha'], 'b': ['beta', 'gamma']}
Upvotes: 0
Reputation: 1764
One more option is the following (without creating a new dict):
for e in [k for k,v in default.iteritems() if len(v) == 0]: default.pop(e)
Upvotes: 2
Reputation: 137514
Michael's answer is correct.
Stepping back, you might be able to avoid creating those empty lists at all, by use of collections.defaultdict(list)
>>> import collections
>>> d = collections.defaultdict(list)
>>> d
defaultdict(<type 'list'>, {})
>>> d["hobbits"].append("Frodo")
>>> d["hobbits"].append("Sam")
>>> d
defaultdict(<type 'list'>, {'hobbits': ['Frodo', 'Sam']})
Upvotes: 1
Reputation: 25032
To fix your function, change del[k]
to del d[k]
. There is no function to delete values in place from a dictionary.
What you are doing is deleting the variable k
, not changing the dictionary at all. This is why the original dictionary is always returned.
Rewritten, your function might look like:
def remove_empty_keys(d):
for k in d.keys():
if not d[k]:
del d[k]
This assumes you want to eliminate both empty list and None
values, and actually removes any item with a "false" value.
Upvotes: 9
Reputation: 213193
You can use dict comprehension: -
>>> default = {'a': ['alpha'], 'b': ['beta','gamma'], 'g': []}
>>> {key: value for key, value in default.iteritems() if value}
{'a': ['alpha'], 'b': ['beta', 'gamma']}
Upvotes: 5
Reputation: 438
dict((k, v) for k, v in default.iteritems() if v)
This filters all items which are not empty strings, empty dict/tuple/list.
Upvotes: 4
Reputation: 309821
There's no builtin for this (AFAIK), but you can do it easily with a dict comprehension:
new_dict = {k:v for k,v in original_dict.items() if v}
If you're stuck with an older version of python (pre 2.7 without dict comprehensions), you can use the dict constructor:
new_dict = dict((k,v) for k,v in original_dict.items() if v)
Note that this doesn't operate in place (as per your second question). And dictionaries don't support slice assignment like lists do, so the best* you can really do to get this all done in place is:
new_dict = {k:v for k,v in original_dict.items() if v}
original_dict.clear()
original_dict.update(new_dict)
*of course the term "best" is completely subjective.
Upvotes: 14