I have below list of dictionaries:
>>> d={}
>>> d['primary info']={"name":"Mark","age":22,"Id":1234}
>>> d['secondary info']={"location":"Pune"}
Now dictionary d has list as following:
{'secondary info': {'location': 'Pune'}, 'primary info': {'age': 22, 'Id': 1234, 'name': 'Mark'}}
How can I remove age key-value pair from primary info?
How can I update value of Id in primary info?
To remove a key, value pair, you can use del:
>>> d = {"bob": "fish", "cat": "dog"}
>>> del d["cat"]
>>> d
{'bob': 'fish'}
As for the second part, you need to get the value of the key "primary info" (another dictionary) and then access the"Id"` value of this, and update it:
d["primary info"]["Id"] = 4321
which I can confirm, updates the value:
{..., 'primary info': {'Id': 4321, 'name': ...}, ...}
To delete a key or value from dict you can use del. For more info regarding del go to this link
You can solve your problem like this..
d={}
d['primary info']={"name":"Mark","age":22,"Id":1234}
d['secondary info']={"location":"Pune"}
del d['primary info']['age'] # deleting
d['primary info']['Id'] = 177 # updating
print(d)
# Output
{'primary info': {'Id': 177, 'name': 'Mark'}, 'secondary info': {'location': 'Pune'}}
Hope this helps..
You can use dictionary comprehension:
d = {'secondary info': {'location': 'Pune'}, 'primary info': {'age': 22, 'Id': 1234, 'name': 'Mark'}}
new_id = 2344
new_d = {a:{c:new_id if c == "Id" else d for c, d in b.items() if c != 'age'} for a, b in d.items()}
Output:
{'primary info': {'Id': 2344, 'name': 'Mark'}, 'secondary info': {'location': 'Pune'}}
Or, you can use recursion for a more robust solution:
def update(d, new_id, delemeter='age'):
if all(not isinstance(b, dict) for a, b in d.items()):
return {a:new_id if a == "Id" else b for a, b in d.items() if a != delemeter}
final_data = {a:update(b, new_id, delemeter=delemeter) for a, b in d.items()}
return final_data
Output:
{'primary info': {'Id': 2344, 'name': 'Mark'}, 'secondary info': {'location': 'Pune'}}
Related
I have a dictionary with missing values (the key is there, but the associated value is empty). For example I want the dictionary below:
dct = {'ID': '', 'gender': 'male', 'age': '20', 'weight': '', 'height': '5.7'}
to be changed to this form:
dct = {'ID': {'link': '','value': ''}, 'gender': 'male', 'age': '20', 'weight': {'link': '','value': ''}, 'height': '5.7'}
I want the ID and Weight key should be replaced with nested dictionary if its empty.
How can I write that in the most time-efficient way?
I have tried solutions from below links but didnt work,
def update(orignal, addition):
for k, v in addition.items():
if k not in orignal:
orignal[k] = v
else:
if isinstance(v, dict):
update(orignal[k], v)
elif isinstance(v, list):
for i in range(len(v)):
update(orignal[k][i], v[i])
else:
if not orignal[k]:
orignal[k] = v
Error: TypeError: 'str' object does not support item assignment
Fill missing keys by comparing example json in python
Adding missing keys in dictionary in Python
It seems similar with this issue https://stackoverflow.com/a/3233356/6396981
import collections.abc
def update(d, u):
for k, v in u.items():
if isinstance(v, collections.abc.Mapping):
d[k] = update(d.get(k, {}) or {}, v)
else:
d[k] = v
return d
For example in your case:
>>> dict1 = {'ID':'', 'gender':'male', 'age':'20', 'weight':'', 'height':'5.7'}
>>> dict2 = {'ID': {'link':'','value':''}, 'weight': {'link':'','value':''}}
>>>
>>> update(dict1, dict2)
{'ID': {'link': '', 'value': ''}, 'gender': 'male', 'age': '20', 'weight': {'link': '', 'value': ''}, 'height': '5.7'}
>>>
You can iterate through the list and see if the value is an empty string('') if it is, replace it with the default value. Here's a small snippet which does it -
dct = {'ID':'', 'gender':'male', 'age':'20', 'weight':'', 'height':'5.7'}
def update(d, default):
for k, v in d.items():
if v == '':
d[k] = default.copy()
update(dct, {'link':'','value':''})
print(dct)
Output :
{'ID': {'link': '', 'value': ''}, 'gender': 'male', 'age': '20', 'weight': {'link': '', 'value': ''}, 'height': '5.7'}
Note that the dict is passed by reference to the function, so any updates made there will be reflected in the original dictionary as well as seen in the above example.
If your dict is nested and you want the replacement to be done for nested items as well then you can use this function -
def nested_update(d, default):
for k, v in d.items():
if v == '':
d[k] = default.copy()
if isinstance(v, list):
for item in v:
nested_update(item, default)
if isinstance(v, dict):
nested_update(v, default)
here's a small example with list of dictionaries and nested dictionary -
dct = {'ID':'', 'gender':'male', 'age':'20', 'weight':'', 'height':'5.7', "list_data":[{'empty': ''}, {'non-empty': 'value'}], "nested_dict": {"key1": "val1", "missing_nested": ""}}
nested_update(dct, {'key1': 'val1-added', 'key2': 'val2-added'})
print(dct)
Output :
{'ID': {'key1': 'val1-added', 'key2': 'val2-added'}, 'gender': 'male', 'age': '20', 'weight': {'key1': 'val1-added', 'key2': 'val2-added'}, 'height': '5.7', 'list_data': [{'empty': {'key1': 'val1-added', 'key2': 'val2-added'}}, {'non-empty': 'value'}], 'nested_dict': {'key1': 'val1', 'missing_nested': {'key1': 'val1-added', 'key2': 'val2-added'}}}
For "this default dictionary to only specified keys like ID and Weight and not for other keys", you can update the condition of when we replace the value -
def nested_update(d, default):
for k, v in d.items():
if k in ('ID', 'weight') and v == '':
d[k] = default.copy()
if isinstance(v, list):
for item in v:
nested_update(item, default)
if isinstance(v, dict):
nested_update(v, default)
I have a dictionary with some values that are type list, i need to convert each list in another dictionary and insert this new dictionary at the place of the list.
Basically, I have this dictionary
Dic = {
'name': 'P1',
'srcintf': 'IntA',
'dstintf': 'IntB',
'srcaddr': 'IP1',
'dstaddr': ['IP2', 'IP3', 'IP4'],
'service': ['P_9100', 'SNMP'],
'schedule' : 'always',
}
I need to reemplace the values that are lists
Expected output:
Dic = {
'name': 'P1',
'srcintf': 'IntA',
'dstintf': 'IntB',
'srcaddr': 'IP1',
'dstaddr': [
{'name': 'IP2'},
{'name': 'IP3'},
{'name': 'IP4'}
],
'service': [
{'name': 'P_9100'},
{'name': 'SNMP'}
],
'schedule' : 'always',
}
So far I have come up with this code:
for k,v in Dic.items():
if not isinstance(v, list):
NewDic = [k,v]
print(NewDic)
else:
values = v
keys = ["name"]*len(values)
for item in range(len(values)):
key = keys[item]
value = values[item]
SmallDic = {key : value}
liste.append(SmallDic)
NewDic = [k,liste]
which print this
['name', 'P1']
['srcintf', 'IntA']
['dstintf', 'IntB']
['srcaddr', 'IP1']
['schedule', 'always']
['schedule', 'always']
I think is a problem with the loop for, but so far I haven't been able to figure it out.
You need to re-create the dictionary. With some modifications to your existing code so that it generates a new dictionary & fixing the else clause:
NewDic = {}
for k, v in Dic.items():
if not isinstance(v, list):
NewDic[k] = v
else:
NewDic[k] = [
{"name": e} for e in v # loop through the list values & generate a dict for each
]
print(NewDic)
Result:
{'name': 'P1', 'srcintf': 'IntA', 'dstintf': 'IntB', 'srcaddr': 'IP1', 'dstaddr': [{'name': 'IP2'}, {'name': 'IP3'}, {'name': 'IP4'}], 'service': [{'name': 'P_9100'}, {'name': 'SNMP'}], 'schedule': 'always'}
I have created 3 different dictionary in python , however I believe this cannot be merged into 1 dictionary e.g. NewDict due to a same Key in all 3 e.g. Name & Company.
NewDict1 = {'Name': 'John,Davies', 'Company': 'Google'}
NewDict2 = {'Name': 'Boris,Barry', 'Company': 'Microsoft'}
NewDict3 = {'Name': 'Humphrey,Smith', 'Company': 'Microsoft'}
I would like to group above in such a way that my output is as below :
Google : John Davies Microsoft : Boris Barry, Humphrey Smith
Any help will be really appreciated .
Use a defaultdict:
from collections import defaultdict
dicts = [NewDict1, NewDict2, NewDict3]
out = defaultdict(list)
for d in dicts:
out[d['Company']].append(d['Name'])
dict(out)
output: {'Google': ['John,Davies'], 'Microsoft': ['Boris,Barry', 'Humphrey,Smith']}
as printed string
for k,v in out.items():
print(f'{k}: {", ".join(v)}')
output:
Google: John,Davies
Microsoft: Boris,Barry, Humphrey,Smith
Why don't you use a different structure for your source dictionary ?
like instead of {'name': 'jack', 'company': 'google'}, go for
dict1 = {'Google': ['Jack']}
dict2 = {'Microsoft': ['Susan']}
dict3= {'Google': ['Amit']}
#then you can combine all three dict into one:
def combine_dict(dict_1, dict_2):
for key in dict_1:
val = dict_1[key]
if key in dict_2:
dict_2[key].extend(val)
else:
dict_2[key] = val
return dict_2
new_dict = combine_dict(dict1,dict2)
new_dict = combine_dict(new_dict, dict3)
this should do it
NewDict1 = {'Name': 'John,Davies', 'Company': 'Google'}
NewDict2 = {'Name': 'Boris,Barry', 'Company': 'Microsoft'}
NewDict3 = {'Name': 'Humphrey,Smith', 'Company': 'Microsoft'}
d = {}
l = [NewDict1, NewDict2, NewDict3]
for each in l:
if each['Company'] not in d.keys():
d[each['Company']] = []
if each['Name'] not in d[each['Company']]:
d[each['Company']].append(each['Name'])
Outputs:
d
{'Google': ['John,Davies'], 'Microsoft': ['Boris,Barry', 'Humphrey,Smith']}
For Plain text
output = ''
for k,v in d.items():
v = [x.replace(',',' ') for x in v]
output+=f" {k}:{','.join(v)}"
output = output.strip()
Print(output) and you get:
'Google:John Davies Microsoft:Boris Barry,Humphrey Smith'
Hello I need to compare 2 dicts but in the result, I need to know from which dict the result came.
dict1 = {'name': 'Morgan', 'surename': 'Finch'}
dict2 = {'name': 'David', 'surename': 'Finch'}
so if I compare with input_data.items() ^ response_data.items() result will something like this:
{('name','Morgan'),('name', 'David)}
expected result should look something like {'dict1': ('name','Morgan'), dict2: ('name', 'David')}
I don't care what data-structure just that I could know from what dict it came.
dict1 = {'name': 'Morgan', 'surname': 'Finch'}
dict2 = {'name': 'David', 'surname': 'Finch'}
# symmetric difference (exclusive OR)
print(dict1.items() ^ dict2.items())
# {('name', 'Morgan'), ('name', 'David')}
# dictionary subtraction
print({'dict1': dict1.items() - dict2.items(), 'dict2': dict2.items() - dict1.items()})
# {'dict1': {('name', 'Morgan')} 'dict2': {('name', 'David')}}
If you want the answer in the form of dictionary
You can use these steps
dict1 = {'name': 'Morgan', 'surename': 'Finch'}
dict2 = {'name': 'David', 'surename': 'Finch'}
dict3 = {}
for k,v in dict1.items():
if dict1[k] != dict2[k]:
dict3['dict1'] = (k,dict1[k])
dict3['dict2'] = (k,dict2[k])
print(dict3)
Output:
{'dict1': ('name', 'Morgan'), 'dict2': ('name', 'David')}
Edit:
If all values are different and want to store in a single key like {'dict1' : ('name', 'Morgan', 'surname', 'Finc'), ... }
dict1 = {'name': 'Morgan', 'surename': 'Finch'}
dict2 = {'name': 'David', 'surename': 'Finc'}
dict3 = {'dict1':(), 'dict2':()}
for k,v in dict1.items():
if dict1[k] != dict2[k]:
dict3['dict1'] += (k,dict1[k])
dict3['dict2'] += (k,dict2[k])
print(dict3)
Output:
{'dict1': ('name', 'Morgan', 'surename', 'Finch'), 'dict2': ('name', 'David', 'surename', 'Finc')}
I have a list of dictionaries in python and I would like to override old value with duplicate value. Please let me know how can I do.
{'message': [{'name': 'raghav', 'id': 10}, {'name': 'raghav', 'id': 11}]}
Output should be:
{'message': [ {'name': 'raghav', 'id': 11}]}
I don't know what you mean by "override old value with duplicate value". If you mean just picking the second dict from the list, you could:
print({k: [v[1]] for (k, v) in data.items()})
If the idea is to update the "name" with a newer value of "id" as you move along the list, then maybe:
def merge_records(data):
records = data['message']
users = {}
for record in records:
name = record['name']
id_ = record['id']
users[name] = id_
new_records = []
for name, id_ in users.items():
new_records.append({'name': name, 'id': id_})
return {'message': new_records}
But, if you have any control over how the data is represented, you might reconsider. You probably want a different data structure.
Here you go:
d = {'message': [{'name': 'raghav', 'id': 10}, {'name': 'raghav', 'id': 11}]}
#loop over outer dictionary
for key, value in d.items():
d[key] = [dict([t for k in value for t in k.items()])]
print(d)
Edit:
As per your requirement:
d = {'message': [ {'name': 'raghav', 'id': 11}, {'name': 'krish', 'id': 20}, {'name': 'anu', 'id': 30}]}
for key, value in d.items():
print [dict((k1,v1)) for k1,v1 in dict([tuple(i.items()) for i in value for val in i.items()]).items()]