1) How we can combine a dict with list and return the result as JSON?
Have tried to combine list_1(dict) and list_2(list), but getting error. Also, after converting them to strings can combine but could not decode back to JSON format(as expected result below).
2) Also, how to replace a value within JSON and maintain it as JSON?
list_1 = [{'title': 'NEWBOOK', 'downloads': '4', 'views': '88'}]
list_2 = {'title': 'MASTERMIND', 'downloads': '16', 'views': '156'}
list_3 = {
'a': 'b',
'c': 'd',
'e': [{
'f': 'g',
'l': 'm'
}]
}
Script which I have tried as below.
combine = list_1 + list_2
for z in list_3['e']:
list_3 = list_3.replace(z, combine)
Expected_json = json.dumps(list_3)
print(list_3)
Error1:
combine = list_1 + list_2
TypeError: can only concatenate list (not "dict") to list
Error2:
list_3 = list_3.replace(z, combine)
AttributeError: 'dict' object has no attribute 'replace'
Expected result:
list_3 = {
"a": "b",
"c": "d",
"e": [{
"f": "g",
"l": "m"
},
{
"title": "NEWBOOK",
"downloads": "4",
"views": "88"
},
{
"title": "MASTERMIND",
"downloads": "16",
"views": "156"
}
]
}
Simply append to the list in the dictionary
list_3['e'].append(list_2)
list_3['e'].append(list_1[0])
print(list_3)
{
'a':
'b',
'c':
'd',
'e': [{
'f': 'g',
'l': 'm'
}, {
'title': 'MASTERMIND',
'downloads': '16',
'views': '156'
}, {
'title': 'NEWBOOK',
'downloads': '4',
'views': '88'
}]
}
import json
list_1 = [{'title': 'NEWBOOK', 'downloads': '4', 'views': '88'}]
list_2 = {'title': 'MASTERMIND', 'downloads': '16', 'views': '156'}
list_3 = {
'a': 'b',
'c': 'd',
'e': [{
'f': 'g',
'l': 'm'
}]
}
list_3['e'].append(list_1[0])
list_3['e'].append(list_2)
json_list = json.dumps(list_3)
if you want to add more lists to the location you do the following
b= json.loads(json_list)
b['e'].append(your_new_dict)
json_list = json.dumps(b)
if you have no idea what list_1 and list_2 are then you can test for the class type and append them accordingly. Like
if(type(list_1)==list):
list_3['e'].append(list_1[0])
if(type(list_2)==dict):
list_3['e'].append(list_2)
if you dont know at which point in list_3 you want to append the list. you do something like the following. Assuming there is only one list in list_3
for x in list_3.values():
if(type(x)==list):
x.append(list_1[0])
x.append(list_2)
Related
a =[{
"id":"1",
"Name":'BK',
"Age":'56'
},
{
"id":"1",
"Sex":'Male'
},
{
"id":"2",
"Name":"AK",
"Age":"32"
}]
I have a list of dictionary with a person information split in multiple dictionary as above for ex above id 1's information is contained in first 2 dictionary , how can i get an output of below
{1: {'Name':'BK','Age':'56','Sex':'Male'}, 2: { 'Name': 'AK','Age':'32'}}
You can use a defaultdict to collect the results.
from collections import defaultdict
a =[{ "id":"1", "Name":'BK', "Age":'56' }, { "id":"1", "Sex":'Male' }, { "id":"2", "Name":"AK", "Age":"32" }]
results = defaultdict(dict)
key = lambda d: d['id']
for a_dict in a:
results[a_dict.pop('id')].update(a_dict)
This gives you:
>>> results
defaultdict(<class 'dict'>, {'1': {'Name': 'BK', 'Age': '56', 'Sex': 'Male'}, '2': {'Name': 'AK', 'Age': '32'}})
The defaultdict type behaves like a normal dict, except that when you reference an unknown value, a default value is returned. This means that as the dicts in a are iterated over, the values (except for id) are updated onto either an existing dict, or an automatic newly created one.
How does collections.defaultdict work?
Using defaultdict
from collections import defaultdict
a = [{
"id": "1",
"Name": 'BK',
"Age": '56'
},
{
"id": "1",
"Sex": 'Male'
},
{
"id": "2",
"Name": "AK",
"Age": "32"
}
]
final_ = defaultdict(dict)
for row in a:
final_[row.pop('id')].update(row)
print(final_)
defaultdict(<class 'dict'>, {'1': {'Name': 'BK', 'Age': '56', 'Sex': 'Male'}, '2': {'Name': 'AK', 'Age': '32'}})
You can combine 2 dictionaries by using the .update() function
dict_a = { "id":"1", "Name":'BK', "Age":'56' }
dict_b = { "id":"1", "Sex":'Male' }
dict_a.update(dict_b) # {'Age': '56', 'Name': 'BK', 'Sex': 'Male', 'id': '1'}
Since the output the you want is in dictionary form
combined_dict = {}
for item in a:
id = item.pop("id") # pop() remove the id key from item and return the value
if id in combined_dict:
combined_dict[id].update(item)
else:
combined_dict[id] = item
print(combined_dict) # {'1': {'Name': 'BK', 'Age': '56', 'Sex': 'Male'}, '2': {'Name': 'AK', 'Age': '32'}}
from collections import defaultdict
result = defaultdict(dict)
a =[{ "id":"1", "Name":'BK', "Age":'56' }, { "id":"1", "Sex":'Male' }, { "id":"2", "Name":"AK", "Age":"32" }]
for b in a:
result[b['id']].update(b)
print(result)
d = {}
for p in a:
id = p["id"]
if id not in d.keys():
d[id] = p
else:
d[id] = {**d[id], **p}
d is the result dictionary you want.
In the for loop, if you encounter an id for the first time, you just store the incomplete value.
If the id is in the existing keys, update it.
The combination happens in {**d[id], **p}
where ** is unpacking the dict.
It unpacks the existing incomplete dict associated withe the id and the current dict, then combine them into a new dict.
from the given input
lists = ["7ee57f24", "deadbeef"]
I want to get the following output
l1': [
{
'd':
{
'id': '7ee57f24'
}
},
{
'd':
{
'id': 'deadbeed'
}
}
]
I have tried this code
lists = ["7ee57f24", "deadbeef"]
l1 = {"d":[{"id": lis} for lis in lists]}
print(l1)
but it gives me wrong output
{'d': [{'id': '7ee57f24'}, {'id': 'deadbeef'}]}
Use the following:
lists = ["7ee57f24", "deadbeef"]
l1 = [
{"d": {"id": id_}}
for id_ in lists
]
print(l1)
Output:
[{'d': {'id': '7ee57f24'}}, {'d': {'id': 'deadbeef'}}]
I have nested dictionary with this kind of structure:
d = {
"A":{
"Param1":"7",
"Param2":"5",
},
"B":{
"Param1":"1",
"Param2":"2",
},
"C":{
"Param1":"X",
"Param2":"Y",
},
"D":{
"SomeOtherParam1": "a",
"SomeOtherParam2": "3",
}
}
How to get dictionary key by nested key names and parameters? For example: Param1=1 and Param2=2 the output should be B. Is it even possible to do that?
UPDATE
Thanks to #deceze here is exactly what I wanted to achieve:
pexist = next((k for k, v in d.items() if v.get('Param1') and v.get('Param2') if v['Param1'] == '1' and v['Param2'] == '2'), None)
if pexist == None:
print("Does not exist!")
else:
print(pexist)
A pandas module based solution:
import pandas as pd
df = pd.DataFrame({'A': {'Param1': '7', 'Param2': '5'}, 'B': {'Param1': '1', 'Param2': '2'}, 'C': {'Param1': 'X', 'Param2': 'Y'}})
s = (df.loc['Param1'] == '1') & (df.loc['Param2'] == '2')
print(*s[s].keys())
Output:
B
I have this json with different levels:
[{'A': 1, 'B': 2, 'CA': {'CA1': '3', 'CA23': '4'}},
{'A': 1, 'B': {'CA1': '3'}, 'CA': {'CA1': '3', 'CA23': '4'}}]
And I want to get only the values for each row using list comprehension:
The expected result is:
[[1, 2, '3', '4'], [1, '3', '3', '4']]
Without using list comprehension this code work:
values = []
for row in json:
rows = []
for item in row.items():
if str(row[item[0]]).startswith("{"):
temp = row[item[0]].values()
else:
temp = [row[item[0]]]
rows.extend(temp)
values.append(rows)
Some ideas?
Here's a way to do it that cheats a little by using an auxiliary helper function to flatten the nested dictionary objects comprising each "row" of your data-structure.
import json # For pretty-printing data and results.
from collections.abc import MutableMapping
def flatten(nested):
''' Yield values from nested dictionary data structure. '''
for value in nested.values():
if isinstance(value, MutableMapping): # Nested?
yield from flatten(value)
else:
yield value
json_values = [{'A': 1, 'B': 2, 'CA': {'CA1': '3', 'CA23': '4'}},
{'A': 1, 'B': {'CA1': '3'}, 'CA': {'CA1': '3', 'CA23': '4'}}]
print('Before:')
print(json.dumps(json_values, indent=4))
# Here's the list comprehension.
result = [list(flatten(nested)) for nested in json_values]
print()
print('After:')
print(json.dumps(result, indent=4))
Output:
Before:
[
{
"A": 1,
"B": 2,
"CA": {
"CA1": "3",
"CA23": "4"
}
},
{
"A": 1,
"B": {
"CA1": "3"
},
"CA": {
"CA1": "3",
"CA23": "4"
}
}
]
After:
[
[
1,
2,
"3",
"4"
],
[
1,
"3",
"3",
"4"
]
]
There are two lists:
customer_list = ["A7", "A8", "A9", "A10", "A11"]
customer_index = ["8", "9", "10", "11", "12"]
The goal is to create the following:
final_list = [
{
"kind": "report#variable",
"type": "A7",
"value": line[8]}
,
{
"kind": "report#variable",
"type": "A8",
"value": line[9]}
,
{
"kind": "report#variable",
"type": "A9",
"value": line[10]}
,
{
"kind": "report#variable",
"type": "A10",
"value": line[11]}
,
{
"kind": "report#variable",
"type": "A11",
"value": line[12]}
]
I tried to use the following Python code, but it did not work:
def create_final_list(list_1, list_2):
new_list = []
list_prefix = '{"kind": "report#variable",'
for num in list_1:
for val in list_2:
list_1_num = ' "type": ' + num
list_2_val = ' "value": ' + val
new_list.append(list_prefix + list_1_num + list_2_val)
return new_list
How does one automatically create a list of Dictionaries based upon two lists of equal length and the desired format as in the above example?
This is not a JSON; but a list of dictionaries which you create in a list-comprehension with zip():
customer_list = ["A7", "A8", "A9", "A10", "A11"]
customer_index = ["8", "9", "10", "11", "12"]
line = [1,2,3,4,5,6,7,8,9,101,11,12,13,14] # assume this `line` list
res = [{"kind": "report#variable", "type": x, "value": line[int(y)]} for x, y in zip(customer_list, customer_index)]
As is in the comments, you can then do:
json.dumps(res)
..to convert res to a JSON string.
Since pandas is tagged, adding another way using a dataframe and groupby:
df = pd.DataFrame({"kind": "report#variable","type":customer_list,"value":customer_index})
final = [g.droplevel(0).to_dict() for _,g in df.stack().groupby(level=0)]
[{'kind': 'report#variable', 'type': 'A7', 'value': '8'},
{'kind': 'report#variable', 'type': 'A8', 'value': '9'},
{'kind': 'report#variable', 'type': 'A9', 'value': '10'},
{'kind': 'report#variable', 'type': 'A10', 'value': '11'},
{'kind': 'report#variable', 'type': 'A11', 'value': '12'}]
Try
lis = []
for i in range(len(customer_index)):
dic = {"type" : customer_list[i], "value" : customer_index[i]}
lis.append(dic)
This outputs
[{'type': 'A7', 'value': '8'},
{'type': 'A8', 'value': '9'},
{'type': 'A9', 'value': '10'},
{'type': 'A10', 'value': '11'},
{'type': 'A11', 'value': '12'}]
As in your code, if you want line[8], do line[customer_index[i]] instead of customer_index[i] during dictionary initialization. Also, add 1 more key of kind in the dictionary, as per your requirement.
The above code works only if both customer_list and customer_index are of equal length, because the loop iterates n number of times, where n is the equal length of the list.