Python: An elegant way to delete empty lists from Python dictionary

前端 未结 6 646
庸人自扰
庸人自扰 2021-01-11 19:30

I have a dictionary as:

default = {\'a\': [\'alpha\'], \'b\': [\'beta\',\'gamma\'], \'g\': []}

I wish to eliminate the empty values as:

相关标签:
6条回答
  • 2021-01-11 19:37

    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.

    0 讨论(0)
  • 2021-01-11 19:44

    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']}
    
    0 讨论(0)
  • 2021-01-11 19:49

    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']})
    
    0 讨论(0)
  • 2021-01-11 19:51

    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.

    0 讨论(0)
  • 2021-01-11 19:59

    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)
    
    0 讨论(0)
  • 2021-01-11 20:00
    dict((k, v) for k, v in default.iteritems() if v)
    

    This filters all items which are not empty strings, empty dict/tuple/list.

    0 讨论(0)
提交回复
热议问题