I am stuck on convert jsons from regular (key-value) to nested.
for example:
j = { 'a': 5,
'b': 3,
'c.c1': 2,
'c.c2':5,
'd.dd.d1': 0,
'd.dd.d2':9
}
and I need to get:
new_j = {
'a': 5,
'b': 3,
'c':
{'c1': 2,
'c2':5}
'd':
{'dd' :
{'d1': 0,
'd2': 9}
},
}
there are easy method to do this?
How about this?
j_new = {}
for key,value in j.items():
keys = key.split('.')
level = j_new
for key in keys[:-1]:
if key not in level:
level[key]={}
level = level[key]
level[keys[-1]]=value
print(j_new)
Which returns:
{'a': 5, 'b': 3, 'c': {'c1': 2, 'c2': 5}, 'd': {'dd': {'d1': 0, 'd2': 9}}}
Try this:
d = {}
def setValue(dic, keys, value):
for key in keys[:-1]:
dic = dic.setdefault(key, {})
dic[keys[-1]] = value
for k,v in j.items():
setValue(d, k.split('.'), v)
Output:
{
"a": 5,
"c": {
"c2": 5,
"c1": 2
},
"b": 3,
"d": {
"dd": {
"d2": 9,
"d1": 0
}
}
}
Related
I have nested dict something like that
my_dict= {'name1': {'code1': {'brand1': 2}},'name2': {'code2.1': {'brand2.1': 2,'brand2.2': 8,'brand2.3': 5, 'brand2.4': 4},'code2.2': {'brand2.1': 2, 'brand1': 1, 'brand2.5': 25}},'name3': {'code1': {'brand2.1': 2},'code3': {'brand4': 1,'brand3.1':2}}}
I need sort on the level "code" with depending on summing values "brands". For example,
target_dict= {'name1': {'code1': {'brand1': 2}}, 'name2': {'code2.2': {'brand2.1':2,'brand1': 1,'brand2.5': 25},'code2.1': {'brand2.1': 2,'brand2.2': 8,'brand2.3': 5,'brand2.4': 4}}, 'name3': {'code3': {'brand4': 1, 'brand3.1':2},'code1': {'brand2.1': 2}}}
*# 'code2.2' first because 2+1+25=28 > 2+8+5+4=19
# 'code3' first because 1+2=3 > 2
I can sum values "brands" by "code" with
sum_values = [[[i, sum(v[i].values())] for i in v.keys()] for x,y in v.items() for k,v in my_dict.items()]
and try combine with sort function as
target_dict = sorted(my_dict.items(), key=lambda i: [[[i, sum(v[i].values())] for i in v.keys()] for x,y in v.items() for k,v in my_dict.items()], reverse=True).
Thanks for your attention and help!
Try (assuming sufficient version of Python to preserve creation order of dict):
my_dict = {
"name1": {"code1": {"brand1": 2}},
"name2": {
"code2.1": {"brand2.1": 2, "brand2.2": 8, "brand2.3": 5, "brand2.4": 4},
"code2.2": {"brand2.1": 2, "brand1": 1, "brand2.5": 25},
},
"name3": {"code1": {"brand2.1": 2}, "code3": {"brand4": 1, "brand3.1": 2}},
}
out = {
k: dict(sorted(v.items(), key=lambda d: sum(d[1].values()), reverse=True))
for k, v in my_dict.items()
}
print(out)
Prints:
{
"name1": {"code1": {"brand1": 2}},
"name2": {
"code2.2": {"brand2.1": 2, "brand1": 1, "brand2.5": 25},
"code2.1": {"brand2.1": 2, "brand2.2": 8, "brand2.3": 5, "brand2.4": 4},
},
"name3": {"code3": {"brand4": 1, "brand3.1": 2}, "code1": {"brand2.1": 2}},
}
I'd like to sum up all values in multiple Python dictionaries with the same key and keep the other values as is if they have a different key.
The input dictionaries would look something like this:
dict1 = {'A':{'a':1, 'b':2, 'c':0}, 'B':{'a':3, 'b':0, 'c':0}}
dict2 = {'A':{'a':3, 'c':1, 'd':5}, 'B':{'a':2, 'b':0, 'c':1}, 'C':{'a':1, 'b':2, 'c':1}}
Output:
dict3 = {'A':{'a':4, 'b':2, 'c':1, 'd':5}, 'B':{'a':5, 'b':0, 'c':1}, 'C':{'a':1, 'b':2, 'c':1}}
Is there any way to achieve this result using only the standard library? This should also work with more than 2 dictionaries.
Very structure dependent, however something like ...
dicts = [
{'A':{'a':1, 'b':2, 'c':0}, 'B':{'a':3, 'b':0, 'c':0}},
{'A':{'a':3, 'c':1, 'd':5}, 'B':{'a':2, 'b':0, 'c':1}, 'C':{'a':1, 'b':2, 'c':1}}
]
odict = {}
for d in dicts:
for dk in d.keys():
if dk not in odict:
odict[dk] = {}
for inner_dk in d[dk].keys():
if inner_dk not in odict[dk]:
odict[dk][inner_dk] = d[dk][inner_dk]
else:
odict[dk][inner_dk] += d[dk][inner_dk]
print(odict)
A function that accepts multiple dicts:
dict1 = {"A": {"a": 1, "b": 2, "c": 0}, "B": {"a": 3, "b": 0, "c": 0}}
dict2 = {
"A": {"a": 3, "c": 1, "d": 5},
"B": {"a": 2, "b": 0, "c": 1},
"C": {"a": 1, "b": 2, "c": 1},
}
def merge_dicts(*dicts):
if not dicts:
return
out = {}
all_keys = set(dicts[0]).union(k for d in dicts[1:] for k in d)
for k in all_keys:
out[k] = {}
for kk in set(dicts[0].get(k, {})).union(
k_ for d in dicts[1:] for k_ in d.get(k, {})
):
out[k][kk] = sum(d.get(k, {}).get(kk, 0) for d in dicts)
return out
print(merge_dicts(dict1, dict2))
Prints:
{'C': {'c': 1, 'a': 1, 'b': 2}, 'A': {'c': 1, 'd': 5, 'a': 4, 'b': 2}, 'B': {'c': 1, 'a': 5, 'b': 0}}
For input:
dict1 = {"A": {"a": 1, "b": 2, "c": 0}, "B": {"a": 3, "b": 0, "c": 0}}
dict2 = {
"A": {"a": 3, "c": 1, "d": 5},
"B": {"a": 2, "b": 0, "c": 1},
"C": {"a": 1, "b": 2, "c": 1},
}
dict3 = {
"A": {"a": 100},
}
print(merge_dicts(dict1, dict2, dict3))
Prints:
{'A': {'a': 104, 'b': 2, 'c': 1, 'd': 5}, 'B': {'a': 5, 'b': 0, 'c': 1}, 'C': {'a': 1, 'b': 2, 'c': 1}}
I got a dict of dicts which looks like this:
d {
1: {
a: 'aaa',
b: 'bbb',
c: 'ccc'
}
2: {
d: 'dddd',
a: 'abc',
c: 'cca'
}
3: {
e: 'eee',
a: 'ababa',
b: 'bebebe'
}
}
I want to convert by dict like this
d {
a: 1,2,3
b: 1,3
c: 1,2
d: 2
e: 3
}
How can I achieve this?I tried reversing it but it throws unhashable dict.
a = {
1: {
"a": "aaa",
"b": "bbb",
"c": "ccc"
},
2: {
"d": "ddd",
"a": "abc",
"c": "cca"
},
3: {
"e": "eee",
"a": "ababa",
"b": "bebebe"
}
}
from collections import defaultdict
b = defaultdict(list)
for i, v in a.items():
for j in v:
b[j].append(i)
The result b is:
defaultdict(<class 'list'>, {'a': [1, 2, 3], 'b': [1, 3], 'c': [1, 2], 'd': [2], 'e': [3]})
You just need to figure out the logic for it. Iterate through the main dictionary, and use the keys of the sub dictionaries to build your new dict.
d = {
1: {
'a': 'aaa',
'b': 'bbb',
'c': 'ccc'
},
2: {
'd': 'dddd',
'a': 'abc',
'c': 'cca'
},
3: {
'e': 'eee',
'a': 'ababa',
'b': 'bebebe'
}
}
newdict = {}
for k,v in d.items():
for keys in v:
newdict.setdefault(keys,[]).append(k)
print(newdict)
how to recursively sort all nested iterable in an iterable?
e.g.
d = {
'e': [{'y': 'y'}, {'x': [{'2': 2, '1': 1}]}],
'x': ['c', 'b', 'a'],
'z': {
'a': [3, 1, 2],
'd': [{'y': [6,5,1]}, {'w': 1}],
'c': {'2': 2, '3': 3, '4': 4}
},
'w': {1:1, 2:2, 3:3}
}
I was the output like
{'e': [{'x': [{'1': 1, '2': 2}]}, {'y': 'y'}],
'w': {1: 1, 2: 2, 3: 3},
'x': ['a', 'b', 'c'],
'z': {'a': [1, 2, 3],
'c': {'2': 2, '3': 3, '4': 4},
'd': [{'w': 1}, {'y': [1, 5, 6]}]}}
from pprint import pprint
d = {
'e': [{'y': 'y'}, {'x': [{'2': 2, '1': 1}]}],
'x': ['c', 'b', 'a'],
'z': {
'a': [3, 1, 2],
'd': [{'y': [6,5,1]}, {'w': 1}],
'c': {'2': 2, '3': 3, '4': 4}
},
'w': {1:1, 2:2, 3:3}
}
def rec_sort(iterable):
"""Recursively sort
"""
def sort_dict_key(x):
if isinstance(x, dict):
return sorted(x.keys(), key=sort_dict_key)
return x
if isinstance(iterable, dict):
d = {}
for k, v in iterable.items():
d[k] = rec_sort(v)
elif isinstance(iterable, list):
iterable.sort(key=sort_dict_key)
for pos,item in enumerate(iterable):
iterable[pos] = rec_sort(item)
return iterable
pprint(rec_sort(d))
You can use recursion:
import json
d = {'x': ['c', 'b', 'a'], 'z': {'a': [3, 1, 2], 'c': {'3': 3, '2': 2, '4': 4}, 'd': [{'y': [6, 5, 1]}, {'w': 1}]}, 'e': [{'y': 'y'}, {'x': [{'1': 1, '2': 2}]}], 'w': {1: 1, 2: 2, 3: 3}}
def sort_nested(c):
if not isinstance(c, dict):
return sorted(c) if isinstance(c, list) else c
return {a:sorted(sort_nested(i) for i in b) if isinstance(b, list) else sort_nested(b) for a, b in c.items()}
print(json.dumps(sort_nested(d), indent=4))
Output:
{
"x": [
"a",
"b",
"c"
],
"z": {
"a": [
1,
2,
3
],
"c": {
"3": 3,
"2": 2,
"4": 4
},
"d": [
{
"w": 1
},
{
"y": [
1,
5,
6
]
}
]
},
"e": [
{
"x": [
{
"1": 1,
"2": 2
}
]
},
{
"y": "y"
}
],
"w": {
"1": 1,
"2": 2,
"3": 3
}
}
I have the below json, I want to add one more property:
[ {
"A": 1,
"B": "str"
},
{
"A": 2,
"B": "str2"
},
{
"A": 3,
"B": "str3"
}
]
So I want something like this:
[ {
"A": 1,
"B": "str",
"C": "X"
},
{
"A": 2,
"B": "str2",
"C": "X"
},
{
"A": 3,
"B": "str3",
"C": "X"
}
]
What is the best way to do this?
Loop through each dict obj in the list and add required key value pair that you want:
List Before
list1 = [
{
"A": 1,
"B": "str"
},
{
"A": 2,
"B": "str2"
},
{
"A": 3,
"B": "str3"
}
]
The code
for l in list1:
l['C'] = 'X'
print(list1)
List After i.e Output
[{'A': 1, 'B': 'str', 'C': 'X'}, {'A': 2, 'B': 'str2', 'C': 'X'}, {'A': 3, 'B': 'str3', 'C': 'X'}]
>>> j = [ { "A": 1, "B": "str" }, { "A": 2, "B": "str2" }, { "A": 3, "B": "str3" } ]
>>> [i.update({'C': 'X'}) for i in j]
>>> j
[{'A': 1, 'B': 'str', 'C': 'X'}, {'A': 2, 'B': 'str2', 'C': 'X'}, {'A': 3, 'B': 'str3', 'C': 'X'}]
Or, as per coldspeed's comment:
>>> for item in j:
... item['C'] = 'X'
...
>>> j
[{'A': 1, 'B': 'str', 'C': 'X'}, {'A': 2, 'B': 'str2', 'C': 'X'}, {'A': 3, 'B': 'str3', 'C': 'X'}]