Reputation: 884
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
Reputation: 184345
If you only need to keep the 1
s then you don't actually have to filter anything, you can just sum the sequence to get the number of 1
s and create a new one with that many 1
s 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
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
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