How do i filter all common sub dictionary keys that exists in other sub dictionary keys in the parent dictionary
d = {
'0': {'key_x': 0, 'key_y': 15, 'key_z': 41}
'1': {'key_x': 5, 'key_y': 22}
'2': {'key_x': 6, 'key_y': 41}
}
result ['key_x', 'key_y']
current solution is
intersect = {}
for k in corner_values.keys():
for j in corner_values[k]:
if j not in intersect:
intersect[j] = 1
else:
intersect[j] += 1
for k in intersect:
if intersect[k] != len(corner_values.keys()):
del intersect[k]
Is there any simpler solution for this?
You can map
the dictionaries to set
and then reduce
using set.intersection
:
>>> from functools import reduce # if you are using Python 3
>>> d = {
... '0': {'key_x': 0, 'key_y': 15, 'key_z': 41},
... '1': {'key_x': 5, 'key_y': 22},
... '2': {'key_x': 6, 'key_y': 41}
... }
>>> reduce(set.intersection, map(set, d.values()))
{'key_x', 'key_y'}
Note: In Python 3, reduce
has been moved to functools
.
Update: As seen in @John's answer, set.intersection
can handle an arbitrary number of sets, so the reduce
is not even necessary. Just set.intersection(*map(set, d.values()))
You can do a single set.intersection
operation once you extract all the keys. It's a one-liner then:
set.intersection(*(set(x) for x in d.itervalues()))
Breaking that down, the first part evaluated is this:
(set(x) for x in d.itervalues())
That's a generator which produces:
{'key_x', 'key_y'}, {'key_x', 'key_y', 'key_z'}, {'key_x', 'key_y'}
In Python 3 that generator is equivalent to:
map(set, d.values())
But in Python 2, map
is less efficient because it constructs a list
that we don't need (as does values()
instead of itervalues()
).
In any case, the results of that generator are passed to set.intersection
(using the *
argument unpacker) to do the heavy lifting in a single call.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With