List comprehension getting values from JSON - python

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"
]
]

Related

Delete key:value pair from dict in list in nested dict

Lets say I have this dict:
dictos = {
"a": {
"b": {
"c": 3,
"d": 4,
"e": [],
"f": [{"g": 5}, 'test', {"h": 6, "i": 7}]
}
}
}
And lets say I want to delete "c": 3 pair. What I am doing:
import dpath.util
path = "a/b/c"
dpath.util.delete(dictos, path)
It is working great. The output is:
{
'a': {
'b': {
'd': 4,
'e': [],
'f': [{'g': 5}, 'test', {'h': 6, 'i': 7}]
}
}
}
The problem is when I am trying to delete key:value pair inside the list.
Lets say I want to delete "h":6. So when doing:
path = "a/b/f[2]/h"
dpath.util.delete(dictos, path)
I am getting:
dpath.exceptions.PathNotFound: Could not find a/b/f[2]/h to delete
it.
So the question basically is how to delete items from nested dicts that are in a list?
It seems the library expects the same separator to be used for all segments i.e. use a/b/f/2/h
path = "a/b/f/2/h"
dpath.util.delete(dictos, path)
print(dictos)
Result:
{'a': {'b': {'d': 4, 'e': [], 'f': [{'g': 5}, 'test', {'i': 7}]}}}

creating a list of dictionary in python

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'}}]

Get key from dictionary by values and keys from nested dictionary in Python

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

How to combine a list and dictionary in Python?

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)

Identify frequency of elements in each key in python

I have a list of dictionary as follows.
mylist = [ {"0": ["code1", "code5"], "1" ["code8", "code7", "code2"]},
{"1": ["code2", "code3"], "2" ["code4", "code5", "code7"], "3": ["code1", "code10"]},
{"0": ["code8", "code5", "code1"], "2" ["code7", "code5", "code2"]} ]
Now, I want to calculate the codes count for each key in the dictionary. For example "0": ["code1", "code5"] and "0": ["code8", "code5"] should give: mydict_for_0 = {"code1": 1, "code5": 2, "code8": 1}
So, for the above mylist the output should be;
mydict_for_0 = {"code1": 2, "code5": 2, "code8": 1}
mydict_for_1 = {"code2": 2, "code3": 1, "code7": 1, "code8": 1}
mydict_for_2 = {"code4": 1, "code5": 2, "code7": 2, {"code2": 1}
mydict_for_3 = {"code1": 1, "code10": 1}
Please help me to do this using python!
Try with defaultdict, Counter from collections module, find all same key's value list, extend them into one list, save into a defaultdict(list):
from collections import defaultdict, Counter
new_dict = defaultdict(list)
for e in mylist:
for key,value in e.items():
new_dict[key].extend(value)
new_dict will be:
defaultdict(list,
{'0': ['code1', 'code5', 'code8', 'code5', 'code1'],
'1': ['code8', 'code7', 'code2', 'code2', 'code3'],
'2': ['code4', 'code5', 'code7', 'code7', 'code5', 'code2'],
'3': ['code1', 'code10']})
After that, loop all items to pass the values list into Counter, to count the occurrences of list:
result = {}
for key,value in new_dict.items():
result['mydict_for_'+key] = dict(Counter(value))
result will be:
{'mydict_for_0': {'code1': 2, 'code5': 2, 'code8': 1},
'mydict_for_1': {'code2': 2, 'code3': 1, 'code7': 1, 'code8': 1},
'mydict_for_2': {'code2': 1, 'code4': 1, 'code5': 2, 'code7': 2},
'mydict_for_3': {'code1': 1, 'code10': 1}}
This might be the solution
final_result = []
for i in mylist:
current_list = mylist[i]
d = {}
for key in current_list:
try:
d[m]+=1
except KeyError as e:
d.update({m: 1})
final_result.append(d)
for i in final_result:
print(i)

Categories