Reputation: 359
I have a dict of dicts dict_of_dicts={1:{'id':1,'name':'joe'},2: {'id':2,'name':'jim'},3: {'id':3,'name':'bob'}}
(the structure is out of my control so I cannot define my dict more conveniently). I am looking to extract the id # (which also corresponds to the key of the upper dict) of the sub dict containing 'name':'bob'
. i.e I want to extract the id value for a specific name.
I have thought of a looping solution, but is there a more pythonic way to go about this? My attempt is below
for i in list(dict_of_dicts.values()):
if i['name']=='bob':
print(i['id'])
Upvotes: 1
Views: 76
Reputation: 655
You can use next() to find the first instance in a generator that satisfy your needs:
dict_of_dicts = {
1: {
'id': 1,
'name': 'joe'
},
2: {
'id': 2,
'name': 'jim'
},
3: {
'id': 3,
'name': 'bob'
}
}
# Find "bob"
try:
id_bob = next(
dict_of_dicts[key]["id"]
for key in dict_of_dicts
if dict_of_dicts[key]["name"] == "bob"
)
except StopIteration:
print("'bob' not found, handle this some way")
raise
# bob_id == 3
If you know for sure that "id"
is the same value as the key
, just use key
instead of dict_of_dicts[key]["id"]
.
Upvotes: 0
Reputation: 6090
A one-liner:
d={1:{'id':1,'name':'joe'},2: {'id':2,'name':'jim'},3: {'id':3,'name':'bob'}}
print ([ k for k,v in d.items() if 'bob' in v['name'] ])
Output:
[3]
Here you get a list of keys/id in case you have multiple ids with `'name':'bob'.
Upvotes: 0
Reputation: 8302
Here is solution you can try out,
search_ = 'bob'
for k, v in dict_of_dicts.items():
if search_ in v.values():
print(f"Id {k}")
break
else:
print("No Match Found")
Edit
def search_(key):
for k, v in dict_of_dicts.items():
if key in v.values():
return k
return -1 # Indicating no match found
Upvotes: 2
Reputation: 487
Alternatively you could use filter
function by passing a lambda that resolves to True
if the name matches the search criteria. I passed in a default value of {'id': None}
when grabbing the first item using next
item if there are no match.
filtered = filter(lambda x: x['name'] == 'bob', dict_of_dicts.values())
match = next(filtered, {'id': None})
print(match['id'])
Upvotes: 0
Reputation: 373
for k, v in dict_of_dicts.items():
if v["name"] == "bob":
print(v["id"])
You can also just print(k)
Upvotes: 1
Reputation: 9197
Even if the structure is out of your control, in case you want to have multiple searches, it might make sense to reformat the data before searchign multiple times, you can match the results later again if needed:
d = {1:{'id':1,'name':'joe'},2: {'id':2,'name':'jim'},3: {'id':3,'name':'bob'}}
n = {e['name']:e['id'] for e in d.values()}
n.get('bob')
#Out[32]: 3
Upvotes: 0