user16108583
user16108583

Reputation: 39

Comparing dictionary and list of dictionaries, and returning value

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

Answers (4)

Sayandip Dutta
Sayandip Dutta

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

Samwise
Samwise

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

Andrej Kesely
Andrej Kesely

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

Sarah Messer
Sarah Messer

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

Related Questions