Reputation: 39
I'm completely new to Python/programming so please bear with me if I did anything stupid or used the wrong approach to solve the problem.
What I'd like to do is to search through/compare a list of dictionaries, and returning "name" if all Keys 1-3 match, or return no match if there is none.
Is there any way to approach this problem, or if not what would be the alternative way?
Below is an example:
Database read from file, converted into list of dict
[{'name': 'Albus', 'Key1': 15, 'Key2': 49, 'Key3': 38},
{'name': 'Cedric', 'Key1': 31, 'Key2': 21, 'Key3': 41},
...
{'name': 'Hagrid', 'Key1': 25, 'Key2': 38, 'Key3': 45}]
Input read from file, converted into dict
{'Key1': 15, 'Key2': 49, 'Key3': 38}
Desired output:
Albus
Upvotes: 0
Views: 91
Reputation: 15872
A Python 3.10+ answer using the new Structural Pattern Matching introduced in python 3.10 and for-else control flow:
data = [{'name': 'Albus', 'Key1': 15, 'Key2': 49, 'Key3': 38},
{'name': 'Cedric', 'Key1': 31, 'Key2': 21, 'Key3': 41},
{'name': 'Hagrid', 'Key1': 25, 'Key2': 38, 'Key3': 45}]
to_match = {'Key1': 15, 'Key2': 49, 'Key3': 38}
for dct in data:
match dct:
case {'name': name, **to_match}:
print(name)
break
else:
print(None)
Output:
Albus
Of course, for older versions this can be refactored like this:
for dct in data:
name = dct['name'] #[1]
if {'name': name, **to_match} == dct: #[2]
print(name)
break
else:
print(None)
Note: In Python 3.8+, line [1] can be omitted, by using walsrus operator in line [2] like this:
if {'name': (name := dct['name']), **to_match} == dct:
Upvotes: 3
Reputation: 71454
If you're going to do a lot of these lookups, I might suggest creating another dict to act as an index.
>>> db = [{'name': 'Albus', 'Key1': 15, 'Key2': 49, 'Key3': 38},
... {'name': 'Cedric', 'Key1': 31, 'Key2': 21, 'Key3': 41},
... {'name': 'Hagrid', 'Key1': 25, 'Key2': 38, 'Key3': 45}]
>>> index_123 = {(d['Key1'], d['Key2'], d['Key3']): d for d in db}
>>> query = {'Key1': 15, 'Key2': 49, 'Key3': 38}
>>>
>>> index_123[tuple(query.values())]['name']
'Albus'
Upvotes: 1
Reputation: 195438
You can use all()
:
lst = [
{"name": "Albus", "Key1": 15, "Key2": 49, "Key3": 38},
{"name": "Cedric", "Key1": 31, "Key2": 21, "Key3": 41},
{"name": "Hagrid", "Key1": 25, "Key2": 38, "Key3": 45},
]
dct = {"Key1": 15, "Key2": 49, "Key3": 38}
for d in lst:
if all(i in d.items() for i in dct.items()):
print(d["name"])
Prints:
Albus
Upvotes: 2
Reputation: 4023
target_name = None
for d in list_of_dicts:
if (target_dict['Key1']==d['Key1']) and (target_dict['Key2']==d['Key2']) and (target_dict['Key3']==d['Key3']):
target_name = d['name']
Upvotes: 1