'Python dictionary tree: Troubles with .copy() when compressing not branching (/serial) segments
How should I compress tree branches when they do not branch?
This is my dictionary:
mydict = {
0: {'c': [], 'p': [1]}, 1: {'c': [0], 'p': [2]}, 2: {'c': [1], 'p': [3]}, 3: {'c': [2], 'p': [7]},
4: {'c': [], 'p': [5]}, 5: {'c': [4], 'p': [6]}, 6: {'c': [5], 'p': [7]},
7: {'c': [3,6], 'p': [8]}, 8: {'c': [7], 'p': [9]}, 9: {'c': [8], 'p':[11]}
10: {'c': [], 'p': [11]}, 11: {'c': [9,10],'p': []}}
As you can see, all keys [0,1,2,3] belong to the same branch and end at a single leaf. For my project I want to group them, such that my final dictionary looks like:
dict2 = {
0: {'c': [], 'p': [7], 'via':[1,2,3]}, 1: {'see':0}, 2: {'see':0}, 3: {'see':0},
4: {'c': [], 'p': [7], 'via':[5,6] }, 5: {'see':4}, 6: {'see':4},
7: {'c': [3,6], 'p': [11], 'via':[8,9] }, 8: {'see':7}, 9: {'see':7},
10: {'c': [], 'p': [11]} 'via':[] },
11: {'c': [9,10],'p': []} 'via':[] }}
I found that rather than making a new dictionary, it messed up my input-dictionary and recherches showed that this is a normal even when using .copy(). I think using copy.deepcopy() makes the code difficult to read. Pandas on the other hand is not suitable either since it is cumbersome to append values to cells, i.e. manipulating lists inside cells.
So now I want to ask how this would be done with clean python code?
(My attempt attached:)
def tree_aggregate(mydict):
tree0 = mydict.copy()
for key, value in list(tree0.items()):
if len(value['c']) == 1:
child = value['c'][0]
if 'via' in tree0[child]:
tree0[child].append(tree0[child]['p'])
else:
tree0[child]['via'] = value['p'].copy()
tree0[child]['p'] = value['p']
...
return tree0
etc...
Note that the tree0[key]= {'see':child} is not yet implemented since this required me to make a function:
def fetch_see(b, dic1):
print (b)
if 'see' in b:
fetch_see(dic1[b['see']],dic1)
else:
return b['c'][0]
Solution 1:[1]
Yes so I solved it but if you think it looks bad I love constructive critique:
import copy
def fetch_see(b, dic1):
if 'see' in dic1[b]:
b2 = fetch_see(dic1[b]['see'],dic1)
return b2
else:
return b
def tree_aggregate(mydict):
tree0 = copy.deepcopy(mydict)
for key, value in list(tree0.items()):
if len(value['c']) == 1:
child = fetch_see(value['c'][0],tree0)
child_v = copy.deepcopy(tree0[child])
tree0[child].setdefault('via',[]).append(child_v['p'][0])
tree0[child]['p'] = copy.deepcopy(value['p'])
tree0[key] = {'see' :child}
return tree0
d_tree5 = tree_aggregate(mydict)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | David Streuli |
