Reputation: 13376
I have a dict of dicts:
d = {
"key1" : {"id" : 5},
"key2" : {"id" : 6},
}
What is the most pythonic way of finding some (doesn't matter which) key in this dict that it's value has a specific key / value pair? In my example I would like something like:
result = find_by_key(d, "id", 5) # should return "key1"
Upvotes: 0
Views: 132
Reputation: 1121554
Using a generator expression and the next()
function:
def find_by_key(d, key, value):
try:
return next(k for k, v in d.iteritems() if (key, value) in v.viewitems())
except StopIteration:
raise KeyError
I assumed you wanted a KeyError
if no matching dictionary is found.
The generator expression filters the dictionary on values that have the key-value pair, as determined by a membership test against the dictionary items view.
This does the minimal amount of work to locate a matching key.
Variations:
In Python 3 dict.items()
is already a view, and iteritems()
has been ditched, so use dict.items()
instead:
return next(k for k, v in d.items() if (key, value) in v.items())
If you want to return a default instead of raising a key error you can have next()
return it:
def find_by_key(d, key, value):
return next(
(k for k, v in d.iteritems() if (key, value) in v.viewitems()),
None)
Demo:
>>> def find_by_key(d, key, value):
... try:
... return next(k for k, v in d.iteritems() if (key, value) in v.viewitems())
... except StopIteration:
... raise KeyError
...
>>> d = {
... "key1" : {"id" : 5},
... "key2" : {"id" : 6},
... }
>>> find_by_key(d, "id", 5)
'key1'
>>> find_by_key(d, "id", 6)
'key2'
>>> find_by_key(d, "id", 7)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in find_by_key
KeyError
Upvotes: 5