compare two different length lists of dictionaries in python - python

I want to compare below dictionaries. Name key in the dictionary is common in both dictionaries.
If Name matched in both the dictionaries, i wanted to do some other stuff with the data.
PerfData = [
{'Name': 'abc', 'Type': 'Ex1', 'Access': 'N1', 'perfStatus':'Latest Perf', 'Comments': '07/12/2017 S/W Version'},
{'Name': 'xyz', 'Type': 'Ex1', 'Access': 'N2', 'perfStatus':'Latest Perf', 'Comments': '11/12/2017 S/W Version upgrade failed'},
{'Name': 'efg', 'Type': 'Cust1', 'Access': 'A1', 'perfStatus':'Old Perf', 'Comments': '11/10/2017 S/W Version upgrade failed, test data is active'}
]
beatData = [
{'Name': 'efg', 'Status': 'Latest', 'rcvd-timestamp': '1516756202.632'},
{'Name': 'abc', 'Status': 'Latest', 'rcvd-timestamp': '1516756202.896'}
]
Thanks
Rajeev

l = [{'name': 'abc'}, {'name': 'xyz'}]
k = [{'name': 'a'}, {'name': 'abc'}]
[i['name'] for i in l for f in k if i['name'] == f['name']]
Hope above logic work for you.

The answer provided didn't assign the result to any variable. If you want to print it, add the following would work:
result = [i['name'] for i in l for f in k if i['name'] == f['name']]
print(result)

Related

List of dictionary need to split and take first only value after split

I have list of dictionary in Python that i want to convert to another list after i split the value in the dictionary and take only first value after the split.
myList = [
{'name': 'CN=John,Li',
'type': 'Agent',
'isMember': False},
{'name': 'CN=Moses,Somewhere',
'type': 'Worker',
'isMember': True},
{'name': 'CN=David, Something',
'type': 'Agent',
'isMember': False}
]
required_fields = ['name', 'isMember']
I'm looking for desired output after splitting the values
myList = [
{'name': 'John',
'isMember': False},
{'name': 'Moses',
'isMember': True},
{'name': 'David',
'isMember': False}
]
Thank you in advance
A small helper function to find the CN=... part from the name, and a list comprehension to loop over myList:
import re
def get_cn(name):
return re.search("CN=([^,]+)", name).group(1)
my_list = [...]
new_list = [
{'name': get_cn(x['name']), 'isMember': x['isMember']}
for x
in my_list
]
print(new_list)
This outputs
[{'name': 'John', 'isMember': False}, {'name': 'Moses', 'isMember': True}, {'name': 'David', 'isMember': False}]
This can be done in single liner -->
new_list = []
for i in range(len(myList)):
new_list.append({"name": re.search("CN=([^,]+)", myList[i]['name']).group(1), \
"isMember":myList[i]['isMember']})
print(new_list)

understanding nested python dict comprehension

I am getting along with dict comprehensions and trying to understand how the below 2 dict comprehensions work:
select_vals = ['name', 'pay']
test_dict = {'data': [{'name': 'John', 'city': 'NYC', 'pay': 70000}, {'name': 'Mike', 'city': 'NYC', 'pay': 80000}, {'name': 'Kate', 'city': 'Houston', 'pay': 65000}]}
dict_comp1 = [{key: item[key] for key in select_vals } for item in test_dict['data'] if item['pay'] > 65000 ]
The above line gets me
[{'name': 'John', 'pay': 70000}, {'name': 'Mike', 'pay': 80000}]
dict_comp2 = [{key: item[key]} for key in select_vals for item in test_dict['data'] if item['pay'] > 65000 ]
The above line gets me
[{'name': 'John'}, {'name': 'Mike'}, {'pay': 70000}, {'pay': 80000}]
How does the two o/ps vary when written in a for loop ? When I execute in a for loop
dict_comp3 = []
for key in select_vals:
for item in test_dict['data']:
if item['pay'] > 65000:
dict_comp3.append({key: item[key]})
print(dict_comp3)
The above line gets me same as dict_comp2
[{'name': 'John'}, {'name': 'Mike'}, {'pay': 70000}, {'pay': 80000}]
How do I get the o/p as dict_comp1 in a for loop ?
The select vals iteration should be the inner one
result = []
for item in test_dict['data']:
if item['pay'] > 65000:
aux = {}
for key in select_vals:
aux[key] = item[key]
result.append(aux)

Python convert multiple lists to dictionary

I have 3 lists:
names = ["john", "paul", "george", "ringo"]
job = ["guitar", "bass", "guitar", "drums"]
status = ["dead", "alive", "dead", "alive"]
I am trying to figure out the best way to combine these lists into a dict like the following:
{"person":{"Name":"john", "Job":"guitar", "Status":"dead"}, "person":{"Name":"paul", "Job":"bass", "Status":"alive"}, "person":{"Name":"george", "Job":"guitar", "Status":"dead"}, "person":{"Name":"ringo", "Job":"drums", "Status":"alive"}}
I have tried using dict(zip) but cannot get it to format like above.
Thanks in advance!
I think what you want is a list of dictionaries. You can zip your three lists together and use a list comprehension. Here's an example:
[
{'name': name, 'job': job, 'status': status}
for name, job, status in zip(names, jobs, statuses)
]
(also renaming your job to jobs and status to statuses)
Which will give you:
[
{'name': 'john', 'job': 'guitar', 'status': 'dead'},
{'name': 'paul', 'job': 'bass', 'status': 'alive'},
{'name': 'george', 'job': 'guitar', 'status': 'dead'},
{'name': 'ringo', 'job': 'drums', 'status': 'alive'}
]
I think this is what you are looking for:
>>> names = ["john", "paul", "george", "ringo"]
>>> job = ["guitar", "bass", "guitar", "drums"]
>>> status = ["dead", "alive", "dead", "alive"]
>>> persons = []
>>> for n, j, s in zip(names, job, status):
... person = { 'name': n, 'job': j, 'status': s }
... persons.append(person)
...
>>> persons
[{'status': 'dead', 'job': 'guitar', 'name': 'john'}, {'status': 'alive', 'job': 'bass', 'name': 'paul'}, {'status': 'dead', 'job': 'guitar', 'name': 'george'}, {'status': 'alive', 'job': 'drums', 'name': 'ringo'}]
>>>
Try this approach:
names = ["john", "paul", "george", "ringo"]
job = ["guitar", "bass", "guitar", "drums"]
status = ["dead", "alive", "dead", "alive"]
two step process:
description =[{'job': j, 'status': s} for j,s in zip(job,status)]
artist ={n: i for n,i in zip(names,description)}}
final output:
print(artist)
{'john': {'job': 'guitar', 'status': 'dead'},
'paul': {'job': 'bass', 'status': 'alive'},
'george': {'job': 'guitar', 'status': 'dead'},
'ringo': {'job': 'drums', 'status': 'alive'}}
you can then do something like this:
artist['ringo']['job']
output:
'drums'

Remove item from nested dictionaries if specified key contains None values

I have a list of dictionaries in which I am trying to remove any dictionary should the value of a certain key is None, it will be removed.
item_dict = [
{'code': 'aaa0000',
'id': 415294,
'index_range': '10-33',
'location': 'A010',
'type': 'True'},
{'code': 'bbb1458',
'id': 415575,
'index_range': '30-62',
'location': None,
'type': 'True'},
{'code': 'ccc3013',
'id': 415575,
'index_range': '14-59',
'location': 'C041',
'type': 'True'}
]
for item in item_dict:
filtered = dict((k,v) for k,v in item.iteritems() if v is not None)
# Output Results
# Item - aaa0000 is missing
# {'index_range': '14-59', 'code': 'ccc3013', 'type': 'True', 'id': 415575, 'location': 'C041'}
In my example, the output result is missing one of the dictionary and if I tried to create a new list to append filtered, item bbb1458 will be included in the list as well.
How can I rectify this?
[item for item in item_dict if None not in item.values()]
Each item in this list is a dictionary. And a dictionary is only appended to this list if None does not appear in the dictionary values.
You can create a new list using a list comprehension, filtering on the condition that all values are not None:
item_dict = [
{'code': 'aaa0000',
'id': 415294,
'index_range': '10-33',
'location': 'A010',
'type': 'True'},
{'code': 'bbb1458',
'id': 415575,
'index_range': '30-62',
'location': None,
'type': 'True'},
{'code': 'ccc3013',
'id': 415575,
'index_range': '14-59',
'location': 'C041',
'type': 'True'}
]
filtered = [d for d in item_dict if all(value is not None for value in d.values())]
print(filtered)
#[{'index_range': '10-33', 'id': 415294, 'location': 'A010', 'type': 'True', 'code': 'aaa0000'}, {'index_range': '14-59', 'id': 415575, 'location': 'C041', 'type': 'True', 'code': 'ccc3013'}]

Updating a value in a dictionary inside a dictionary

If I have a list of contact dictionaries like this:
{'name': 'Rob', 'phoneNumbers': [{'phone': '123-3214', 'type': 'home'}, {'phone': '456-3216', 'type': 'work'}]}
how could I update this dictionary to remove the dashes from the phone numbers in a list of contact dictionaries pythonically?
You could just nest loops:
for contact_dict in list_of_dicts:
for phone_dict in contact_dict['phoneNumbers']:
phone_dict['phone'] = phone_dict['phone'].replace('-', '')
This alters the values in-place.
Or you could create a whole new copy of the structure, with the alterations made:
[dict(contact, phoneNumbers=[
dict(phone_dict, phone=phone_dict['phone'].replace('-', ''))
for phone_dict in contact['phoneNumbers']])
for contact in list_of_dicts]
This creates a semi-shallow copy; only the phoneNumbers key is explicitly copied, but any other mutable values are just referenced by the new dictionaries.
Demo:
>>> list_of_dicts = [{'name': 'Rob', 'phoneNumbers': [{'phone': '123-3214', 'type': 'home'}, {'phone': '456-3216', 'type': 'work'}]}]
>>> [dict(contact, phoneNumbers=[
... dict(phone_dict, phone=phone_dict['phone'].replace('-', ''))
... for phone_dict in contact['phoneNumbers']])
... for contact in list_of_dicts]
[{'phoneNumbers': [{'phone': '1233214', 'type': 'home'}, {'phone': '4563216', 'type': 'work'}], 'name': 'Rob'}]
>>> for contact_dict in list_of_dicts:
... for phone_dict in contact_dict['phoneNumbers']:
... phone_dict['phone'] = phone_dict['phone'].replace('-', '')
...
>>> list_of_dicts
[{'phoneNumbers': [{'phone': '1233214', 'type': 'home'}, {'phone': '4563216', 'type': 'work'}], 'name': 'Rob'}]
Just str.replace the -
d ={'name': "Rob", 'phoneNumbers': [{'phone': '123-3214', 'type': 'home'}, {'phone': '456-3216', 'type': 'work'}]}
for dct in d["phoneNumbers"]:
dct['phone'] = dct['phone'].replace("-","",1)
Which gives you:
{'phoneNumbers': [{'phone': '1233214', 'type': 'home'}, {'phone': '4563216', 'type': 'work'}], 'name': 'Rob'}

Categories