Question

This code:

a = {'sd':{},'sdd':'','sadfas':None,'sadfa':'dsf'}
a = dict((k, v) for k, v in a.iteritems() if v is not '' or v != {} or v is not None)
print a

prints:

{'sdd': '', 'sadfas': None, 'sadfa': 'dsf', 'sd': {}}

However, it does not remove all the type of values from dict which i need to remove. Why is that ?

These values are removed if i do:

a = {'sd':{},'sdd':'','sadfas':None,'sadfa':'dsf'}

a=dict((k, v) for k, v in a.iteritems() if v is not '')
a=dict((k, v) for k, v in a.iteritems() if v is not None)
a=dict((k, v) for k, v in a.iteritems() if v)

print a

This prints:

{'sadfa': 'dsf'}

which is what we want, but i have to iterate over dictionary 3 times in order to achieve. Can you suggest a more optimised way.

Was it helpful?

Solution

There are two issues here:

  1. v is not '' should be v != ''. You should always use == and != to compare two values because is and is not are for comparing the identities of two objects.

  2. You need to use and instead of or. Otherwise, this condition:

    v != '' or v != {} or v is not None
    

    will always be True because v will always be either not equal to '' or not equal to {}.

Below is a fixed version of your code:

>>> a = {'sd':{},'sdd':'','sadfas':None,'sadfa':'dsf'}
>>> a = dict((k, v) for k, v in a.iteritems() if v != '' and v != {} and v is not None)
>>> a
{'sadfa': 'dsf'}
>>>

However, we can simplify this further:

>>> a = {'sd':{},'sdd':'','sadfas':None,'sadfa':'dsf'}
>>> a = dict((k, v) for k, v in a.iteritems() if v)
>>> a
{'sadfa': 'dsf'}
>>>

This solution works because '', {}, and None all evaluate to False.

OTHER TIPS

empties = ('', {}, None)
{k:v for k,v in a.items() if v not in empties}
# for your input this would work too, 
# as all 'emtpies' evaluate to False:
{k:v for k,v in a.items() if v}

# or if you want to remove in-place:
for key in a.keys():
    # if a[key] in empties:
    if not a[key]:
        del a[key]

Above works in python 2.7+, if you need solution for earlier version, you can use dict() and generator comprehension:

dict((k,v) for (k,v) in a.items() if v)
# or
dict(element for element in a.items() if element[1])

You just need this:

dict([x for x in d.items() if x[1]])

becase of '', None, {} stand for the same thing False, when they are used in if.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top