alperovich
alperovich

Reputation: 884

Get new dictionary using filter in python

A have a dictionary like this:

dict = {
 'a':
    {'a1':(1,0,0,1,0), 'a2':(1,1,1,0,0)},
 'b':
    {'b1':(1,1,0,1,1), 'b2':(1,0,1,0,0)}
}

What I want is to make a new dictionary exactly like dict but without zeroes in a tuples

dict_new = {
 'a':
    {'a1':(1,1), 'a2':(1,1,1)},
 'b':
    {'b1':(1,1,1,1), 'b2':(1,1)}
} 

The following is correct:

 >>> a = (1,0,0,1)
 >>> filter(lambda x: x!= 0,a)
 >>> (1,1)

So, what I am trying to do is

 dict_new = filter(
     lambda x: filter(
       lambda y: dict[x][y]!=0), dict[x]), dict)

But the answer is

['a', 'b']

What am I doing wrong? And is that possible to do things like this?

Upvotes: 0

Views: 110

Answers (3)

kindall
kindall

Reputation: 184345

If you only need to keep the 1s then you don't actually have to filter anything, you can just sum the sequence to get the number of 1s and create a new one with that many 1s in it.

dict_input = {
 'a':
    {'a1':(1,0,0,1,0), 'a2':(1,1,1,0,0)},
 'b':
    {'b1':(1,1,0,1,1), 'b2':(1,0,1,0,0)}
}

dict_output = {}

for key, subdict in dict_input.iteritems():
   dict_output[key] = {}
   for subkey, items in subdict.iteritems():
       dict_output[key][subkey] = (1,) * sum(items)

Upvotes: 0

Robᵩ
Robᵩ

Reputation: 168786

If you'd rather have a loop than a dict comprehension:

>>> print adict
{'a': {'a1': (1, 0, 0, 1, 0), 'a2': (1, 1, 1, 0, 0)}, 'b': {'b1': (1, 1, 0, 1, 1), 'b2': (1, 0, 1, 0, 0)}}
>>> newdict = {}
>>> for k in dict:
...   newdict[k] = {}
...   for k2 in adict[k]:
...     newdict[k][k2] = filter(lambda x: x!=0, adict[k][k2])
... 

Upvotes: 0

Martijn Pieters
Martijn Pieters

Reputation: 1124170

You need to loop over the nested structure to apply the filters only to the inner values. Dict comprehensions work fine for that:

dict_new = {kouter: {kinner: tuple(filter(bool, vinner)) for kinner, vinner in vouter.iteritems()} 
            for kouter, vouter in dict_old.iteritems()}

Demo:

>>> {kouter: {kinner: tuple(filter(bool, vinner)) for kinner, vinner in vouter.iteritems()} 
...             for kouter, vouter in dict_old.iteritems()}
{'a': {'a1': (1, 1), 'a2': (1, 1, 1)}, 'b': {'b1': (1, 1, 1, 1), 'b2': (1, 1)}}

Upvotes: 4

Related Questions