Hi new python coder here, let's say I have a list of dictionaries:
data = [{'stat_1': 'name_1', 'stat_2': 10}, {'stat_1': 'name_2', 'stat_2': 12}]
Now I want to add to this list of dictionaries a stat_3 that has the corresponding values for each dictionary item of 100 and 120.
My intended result is:
updated_data = [{'stat_1': 'name_1', 'stat_2': 10, 'stat_3': 100}, {'stat_1': 'name_2', 'stat_2': 12, 'stat_3: 120}]
I know you can append to one dictionary item but how would I go about this with two dictionary items in a list? Is a for loop required? Appreciate the help!
updated_data = data
updated_data[0].update({'stat_3': 100})
updated_data[1].update({'stat_3': 120})
Will sort you, matey.
This should work fine:
data[0]['stat_3'] = 100
data[1]['stat_3'] = 120
if you have a lot of dictionaries in your data list i would do this:
for i in range(len(data)):
data[i]['stat_3'] = value #(whatever value you want)
Here's a one-liner:
data = [{'1': 1, '2': 2}, {'11': 11, '22': 22}]
append = {'C': 'c', 'D': 'd', 'E': 'e'}
[d.update(append) for d in data]
print(data)
As a side-effect, this creates a list full of None as long as len(data). However, no reference to it is saved, so it should be garbage collected immediately.
Output:
[{'1': 1, '2': 2, 'C': 'c', 'D': 'd', 'E': 'e'},
{'11': 11, '22': 22, 'C': 'c', 'D': 'd', 'E': 'e'}]
I am trying to get the key values commonly present in both first_list and second_list as below,first_list and second_list has X and Z as the common keys,I want to get the values corresponding to X and Z and create a final dictionary as show in EXPECTED OUTPUT BELOW,I have the current and expected output,can someone provide guidance on what is wrong here?
first_list = [{'W':['xyz','abc','def']},{'X':['1','2','3']},{'Y':['4','5','6']},{'Z':['1','5','7']}]
second_list = [{'X':True},{'Z':True}]
first_list_keys,second_list_keys = [],[]
for item in first_list:
for key,value in item.items():
print (key,value)
first_list_keys.append(key)
for item in second_list:
for key,value in item.items():
print (key,value)
second_list_keys.append(key)
print(first_list_keys,second_list_keys)
c = set(first_list_keys).intersection(second_list_keys)
print (c)
final_dict = {}
for item in c:
item_dict = {}
for data in first_list:
for key,value in data.items():
print (key,value)
if key == item:
print ('==================')
print (value)
item_dict['deps'] = value
for item in c:
for data in second_list:
for key,value in data.items():
print (key,value)
if key == item:
print ('==================')
print (value)
item_dict['values'] = True
final_dict[key] = item_dict
print (final_dict)
CURRENT OUTPUT:-
{'Z': {'deps': ['1', '5', '7'], 'values': True}}
EXPECTED OUTPUT:-
{'X':{"deps":['1','2','3'],"values": true },'Z':{"deps":['1','5','7'],"values": true }
UPDATE:-
{'W':{"deps":['xyz','abc','def'],"values": False},'X':{"deps":['1','2','3'],"values": True },'Y':{"deps":['4','5','6'],"values":False},'Z':{"deps":['1','5','7'],"values": True }
Here's one solution. Note that to be able to look up the keys in the second list, I first turn it into a dictionary and then work with that. This code assumes that each dictionary in either list consists of exactly one key/value pair:
first_list = [{'W':['xyz','abc','def']},{'X':['1','2','3']},{'Y':['4','5','6']},{'Z':['1','5','7']}]
second_list = [{'X':True},{'Z':True}]
result ={}
# Create a map from "second_list", where for each entry in "second_list", we pull out the one
# key/value pair contained therin and then add it to the new dictionary
second_list_map = { next(iter(kv.keys())):next(iter(kv.values())) for kv in second_list}
# For each entry in the first list...
for fentry in first_list:
# Get the one key in the entry
key = next(iter(fentry.keys()))
# If this key is also in the second list...
if key in second_list_map:
# Add the appropriate entry to the result dictionary
result[key] = {
"deps": fentry[key],
"values": second_list_map[key]
}
print(result)
Result:
{'X': {'deps': ['1', '2', '3'], 'values': True}, 'Z': {'deps': ['1', '5', '7'], 'values': True}}
Here's the main body for the updated requirement of retaining all the values from the first list, and noting the absence of a key in the second list with 'values': False:
for fentry in first_list:
key = next(iter(fentry.keys()))
result[key] = {
"deps": fentry[key],
"values": second_list_map[key] if key in second_list_map else False
}
Result:
{'W': {'deps': ['xyz', 'abc', 'def'], 'values': False}, 'X': {'deps': ['1', '2', '3'], 'values': True}, 'Y': {'deps': ['4', '5', '6'], 'values': False}, 'Z': {'deps': ['1', '5', '7'], 'values': True}}
You can join the two lists into a single list. Then sort the list by the dictionary keys. That will give you the keys next to each other. Check the adjacent element and if the keys match, then you can update your dictionary accordingly. If adjacent keys don't match, then set Values = False.
Here's the code to do it.
first_list = [{'W':['xyz','abc','def']},
{'X':['1','2','3']},
{'Y':['4','5','6']},
{'Z':['1','5','7']}]
second_list = [{'X':True},{'Z':True}]
#combine the two lists, then sort the list by dictionary keys
combined = sorted(first_list + second_list, key=lambda d: sorted(d.keys()))
#setup a dictionary to store final result
fs_final_dict = {}
#set index to 0
i = 0
#iterate through the dictionary and check for adjacent element
while i <= (len(combined)-1):
if i == len(combined)-1:
k1,v1 = [*combined[i].items()][0]
fs_final_dict[k1] = {'deps':v1,'values':False}
i+=1
elif combined[i].keys() == combined[i+1].keys():
k1,v1 = [*combined[i].items()][0]
k2,v2 = [*combined[i+1].items()][0]
fs_final_dict[k1] = {'deps':v1,'values':v2}
i+=2
else:
k1,v1 = [*combined[i].items()][0]
fs_final_dict[k1] = {'deps':v1,'values':False}
i+=1
print (fs_final_dict)
The output will be:
{'W': {'deps': ['xyz', 'abc', 'def'], 'values': False}, 'X': {'deps': ['1', '2', '3'], 'values': True}, 'Y': {'deps': ['4', '5', '6'], 'values': False}, 'Z': {'deps': ['1', '5', '7'], 'values': True}}
A few test cases:
Test Case 1: Passed
second_list = [{'X':True},{'X':True}]
Output is:
{'W': {'deps': ['xyz', 'abc', 'def'], 'values': False}, 'X': {'deps': True, 'values': False}, 'Y': {'deps': ['4', '5', '6'], 'values': False}, 'Z': {'deps': ['1', '5', '7'], 'values': False}}
Test Case 2: Passed
second_list = [{'X':True},{'Y':True}]
{'W': {'deps': ['xyz', 'abc', 'def'], 'values': False}, 'X': {'deps': ['1', '2', '3'], 'values': True}, 'Y': {'deps': ['4', '5', '6'], 'values': True}, 'Z': {'deps': ['1', '5', '7'], 'values': False}}
Test Case 3: Passed
second_list = [{'X':True},{'W':True}]
{'W': {'deps': ['xyz', 'abc', 'def'], 'values': True}, 'X': {'deps': ['1', '2', '3'], 'values': True}, 'Y': {'deps': ['4', '5', '6'], 'values': False}, 'Z': {'deps': ['1', '5', '7'], 'values': False}}
Test Case 4: Passed
second_list = [{'W':True},{'Z':True}]
{'W': {'deps': ['xyz', 'abc', 'def'], 'values': True}, 'X': {'deps': ['1', '2', '3'], 'values': False}, 'Y': {'deps': ['4', '5', '6'], 'values': False}, 'Z': {'deps': ['1', '5', '7'], 'values': True}}
Test Case 5: Passed
Even though value of W is False, I am considering a value exists and I am populating the value in the second_list rather than overriding it with True. If we should make it True, then the code has to change.
second_list = [{'W':False},{'Z':True}]
{'W': {'deps': ['xyz', 'abc', 'def'], 'values': False}, 'X': {'deps': ['1', '2', '3'], 'values': False}, 'Y': {'deps': ['4', '5', '6'], 'values': False}, 'Z': {'deps': ['1', '5', '7'], 'values': True}}
Test Case 6: Failed
second_list has a key that is NOT in first_list. What do you want the code to do? Ignore key and value in second_list or store that as a new entry in final_list? The current code stores it as a new key.
second_list = [{'P':True},{'Z':True}]
{'P': {'deps': True, 'values': False}, 'W': {'deps': ['xyz', 'abc', 'def'], 'values': False}, 'X': {'deps': ['1', '2', '3'], 'values': False}, 'Y': {'deps': ['4', '5', '6'], 'values': False}, 'Z': {'deps': ['1', '5', '7'], 'values': True}}
Test Case 7: Passed
second_list has a key with the value in a list. I am considering it as a value that needs to be appended to final_list. Is this correct?
second_list = [{'W':[True]},{'Z':True}]
{'W': {'deps': ['xyz', 'abc', 'def'], 'values': [True]}, 'X': {'deps': ['1', '2', '3'], 'values': False}, 'Y': {'deps': ['4', '5', '6'], 'values': False}, 'Z': {'deps': ['1', '5', '7'], 'values': True}}
CODE
first_list = [{'W':['xyz','abc','def']},{'X':['1','2','3']},{'Y':['4','5','6']},{'Z':['1','5','7']}]
second_list = [{'X':True},{'Z':True}]
first_dict = {key: value for elem in first_list for key, value in elem.items()}
second_dict = {key: value for elem in second_list for key, value in elem.items()}
newdict={key: {"dept": first_dict[key], "value": second_dict[key]} if key in list(second_dict.keys()) else {"dept": first_dict[key], "value": False} for key in list(first_dict.keys()) }
print(newdict)
output:
{'W': {'dept': ['xyz', 'abc', 'def'], 'value': False}, 'X': {'dept': ['1', '2', '3'], 'value': True}, 'Y': {'dept': ['4', '5', '6'], 'value': False}, 'Z': {'dept': ['1', '5', '7'], 'value': True}}
EXPLAINATION
first step:
first_dict = {key: value for elem in first_list for key, value in elem.items()}
here with a dict comprehension i merge all the dicts stored in first_list
output:
{'W': ['xyz', 'abc', 'def'],
'X': ['1', '2', '3'],
'Y': ['4', '5', '6'],
'Z': ['1', '5', '7']}
second step:
second_dict = {key: value for elem in second_list for key, value in elem.items()}
here with a dict comprehension i merge all the dicts stored in second_list
output:
{'X': True, 'Z': True}
last step:
newdict={key: {"dept": first_dict[key], "value": second_dict[key]} for key in list(first_dict.keys()) if key in list(second_dict.keys())}
here with the last dict comprehension i generate the needed output
Iterating above first_dict i check if the keys are also in second_dict
if the condition occurres i create a new item in the dict, with the shared key as a key and a dict as a value, the nested dict contains under "dept" key the value from the first_dict and under the key "value" the value fron the second_dict
if the condition doesn't occurres i create a new item in the dict, with the non shared key as a key and a dict as a value, the nested dict contains under "dept" key the value from the first_dict and under the key "value" the value False
I created an function to gather the following sample list below:
full_list = ['Group1', [{'a':'1', 'b':'2'},{'c':'3', 'x':'1'}]
'Group2', [{'d':'7', 'e':'18'}],
'Group3', [{'m':'21'}, {'n':'44','p':'13'}]]
As you can see some of the elements inside the lists are made up of key-value pair dictionaries.
And these dictionaries are of different sizes (number of kv pairs).
Can anyone suggest what to use in python to display this list in separate columns?
Group1 Group2 Group3
{'a':'1', 'b':'2'} {'d':'7', 'e':'18'} {'m':'21'}
{'c':'3', 'x':'1'} {'n':'44','p':'13'}
I am not after a solution but rather a point in the right direction for a novice like me.
I have briefly looked at itertools and pandas dataframes
Thanks in advance
Here is one way:
First extract the columns and the data:
import pandas as pd
columns = full_list[::2]
#['Group1', 'Group2', 'Group3']
data = full_list[1::2]
#[[{'a': '1', 'b': '2'}, {'c': '3', 'x': '1'}],
# [{'d': '7', 'e': '18'}],
# [{'m': '21'}, {'n': '44', 'p': '13'}]]
Here the [::2] means iterate from begin to end but only every 2 items and so does [1::2] but it starts iterating from index 1 (second position)
Then create a pd.DataFrame:
df = pd.DataFrame(data)
#0 {'a': '1', 'b': '2'} {'c': '3', 'x': '1'}
#1 {'d': '7', 'e': '18'} None
#2 {'m': '21'} {'n': '44', 'p': '13'}
Ooops but the columns and rows are transposed so we need to convert it:
df = df.T
Then add the columns:
df.columns = columns
And there we have it:
Group1 Group2 Group3
0 {'a': '1', 'b': '2'} {'d': '7', 'e': '18'} {'m': '21'}
1 {'c': '3', 'x': '1'} None {'n': '44', 'p': '13'}
I have nested dictionaries in a list of dictionaries, I want to merge the lists based on 'id'
res = [{'i': ['1'], 'id': '123'},
{'i': ['1'], 'id': '123'},
{'i': ['1','2','3','4','5','6'],'id': '123'},
{'i': ['1'], 'id': '234'},
{'i': ['1','2','3','4','5'],'id': '234'}]
Desired output:
[{'i': [1, 1, 1, 2, 3, 4, 5, 6], 'id': '123'},
{'i': [1, 1, 2, 3, 4, 5], 'id': '234'}]
I am trying to merge the nested dictionaries based on key "id". I couldn't figure out the best way out:
import collections
d = collections.defaultdict(list)
for i in res:
for k, v in i.items():
d[k].extend(v)
The above code is merging all the lists, but i wantto merge lists based on key "id".
Something like this should do the trick
from collections import defaultdict
merged = defaultdict(list)
for r in res:
merged[r['id']].extend(r['i'])
output = [{'id': key, 'i': merged_list} for key, merged_list in merged.items()]
The following produces the desired output, using itertools.groupby:
from operator import itemgetter
from itertools import groupby
k = itemgetter('id')
[
{'id': k, 'i': [x for d in g for x in d['i']]}
for k, g in groupby(sorted(res, key=k), key=k)
]
I'm not sure what the expected behavior should be when there are duplicates -- for example, should the lists be:
treated like a set() ?
appended, and there could be multiple items, such as [1,1,2,3...] ?
doesn't matter -- just take any
Here would be one variation where we use a dict comprehension:
{item['id']: item for item in res}.values()
# [{'i': ['1', '2', '3', '4', '5'], 'id': '234'}, {'i': ['1', '2', '3', '4', '5', '6'], 'id': '123'}]
If you provide a bit more information in your question, I can update the answer accordingly.