Bhargav Amin
Bhargav Amin

Reputation: 1177

Python - Compare two dictionaries [Match case sensitive values]

I'm trying to compare two dictionaries (list containing arrays) in Python.

Here are two dictionaries:

tag=[{'Key': 'Base', 'Value': 'ny'}, {'Key': 'Name', 'Value': 'newyork'}]

filters=[{'Key': 'Name','Value': ['Newyork', 'newyork','NewYork']}]

The task here is to compare filters dict with tag dict.

Following ways I tried which didn't work :

>>> tag == filters
False
>>> tag[1] == filters
False
>>> tag[1] == filters[0]
False

I want to check if tag has an array matching to filters it should return true.

Probably, it is able to compare the value of Keyin the array as it has an exact matching string but for Value which has same string written in different cases, it doesn't match.

The things I want to cover while comparing:

Any help appreciated. Thanks in advance!

Upvotes: 0

Views: 754

Answers (2)

Pete
Pete

Reputation: 3

This takes your Dictionary's converts them to lower case, discards the extra cases(I.E. NewYork, NEWYORK, ETC. and compares the returned Dictionary's for matches.

import re

tag=[{'Key': 'Base', 'Value': 'ny'}, {'Key': 'Name', 'Value': 'newyork'}]
filters=[{'Key': 'Name','Value': ['Newyork', 'newyork','NewYork']}]

def dict_to_lower(dct):
    tmp = []
    for item in dct:
        #check for one value, change to lower case
        if re.search(r'[\,]', str(item['Value'])) is None:
            item['Key'] = str(item['Key']).lower()
            item['Value'] = str(item['Value']).lower()
            tmp.append(item)
        #else multiple values in list, change to lower, discard all but one
        else:
            item['Key'] = str(item['Key']).lower()
            item['Value'] = re.search(r'(\w+)', str(item['Value']).lower()).group(0)
            tmp.append(item)

    dct = tmp


    return dct

def compare_lists(tag, filters):
    #compare tag to filters return matches
    check = set([(d['Key'], d['Value']) for d in filters])
    return [d for d in tag if (d['Key'], d['Value']) in check]

tag = dict_to_lower(tag)
filters = dict_to_lower(filters)

if compare_lists(tag, filters):
    #Rest of your code here

Upvotes: 0

RaGe
RaGe

Reputation: 23677

Those are quite odd data structures to start with, but I recognize those as the sort of things aws cli/api returns. I bet there's a cli/api way to filter for what you're trying to do, you should really post a question about what you're trying to query from aws (see). But ignoring that for the moment:

Note that tag isn't a dictionary, but a list of dictionaries. You need to first pick the dictionary that has Key:Name in it.

next(element for element in tag if element['Key'] == 'Name')
=> {'Key': 'Name', 'Value': 'newyork'}

Or rather, you want to select the dictionary that has the same Key:xxx as your filter.

next(element for element in tag if element['Key'] == filters[0]['Key'])
=> {'Key': 'Name', 'Value': 'newyork'}

Now you want to compare the Value from selected dictionary with your filter Value

selectedDict=next(element for element in tag if element['Key'] == filters[0]['Key'])
selectedDict['Value'] in filters[0]['Value']
=> True

In one line,

next(element for element in tag if element['Key'] == filters[0]['Key'])['Value'] in filters[0]['Value']
=> True

Upvotes: 1

Related Questions