Reputation: 1177
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 Key
in 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:
key
and values
: 'Name','name','NAME'
and 'Newyork', 'newyork','NewYork'
Any help appreciated. Thanks in advance!
Upvotes: 0
Views: 754
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
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