I have 2 dictionaries and one of them is nested. I would like to create another nested dictionary by checking keys and values of these two dictionaries. 'dict1' gives the connections between the key and the elements of the list:
dict1={'A': ['K', 'J'], 'C': ['A'], 'D': ['B', 'C']}
dict2 has same keys (less or more) with values compared to dict1 as:
dict2={'D': {'D': '0.20','B': '0.20','C': '0.00','A': '0.06','K': '0.00','J': '0.02'},'A': {'A': '0.21', 'K': '0.00', 'J': '0.08'}}
For a given key in the first level and all the other keys in the second level of dict2, I would like to create a nested dictionary which checks dict1 and its list to see the connections. If an element from the list of dict1 (which matches with second level of the nested dict2) has zero value in dict2, it should checks its list connection in dict1, and do the connection with dict1 elements until it reaches to non-zero value. For instance, 'D' in dict1 has list of ['B','C']. 'B':0.20 which is non-zero in dict2 so we can do connection as ('D','B',[]). Then, we check for 'D' and 'C'. Given 'D' and 'C':'0.00', we check dict1 for 'C' and see that it has list of ['A'] which is non-zero in dict2 ('A': '0.06') so we get ('D','A',[C]). If 'A' was zero in dict2 then we should have checked dict1 to see that 'A': [['K', 'J'] then check whether 'K' and 'J' are non-zero. If they were non-zero then we should have gotten ('D','K',['C','A']) and (D,J,['C','A']). Given these, I would like to obtain a nested dictionaries like below so that I can have the connections and list of keys which are like intermediary within my connections:
result={'D': {('D','B',[]),('D','A',['C']),('A','J',[])}'A':{('A','K',[]),('A','J',[])}}
'result' should give me the connections and also the list that shows if I have had any element between the connected ones while creating the connections. This is how far I could get but I cant get my intended output whereas I have bigger data unlike the example here so I should generalize my code below and consider the cases for which I can have multiple zeros in dict2 so I need to check dict1 multiple times:
keysList = list(dict1.keys())
ex_dict2={'D': {'D': '0.20', 'B': '0.20', 'C': '0.00', 'A': '0.06', 'K': '0.00', 'J': '0.02'}}
for target in ex_dict2:
print(ex_dict2)
for key in dict1:
#print(key)
for i in dict1[key]:
t=(key,i)
if ex_dict2[target][key]!='0.00' and ex_dict2[target][i]!='0.00':
output.append(t)
else:
if ex_dict2[target][i]=='0.00' and i in keysList :
print(t)
tt=(t,[i])
output.append(tt)
test_dict[target]=output
my output looks like:
{'D': [('A', 'J'), ('D', 'B'), (('D', 'C'), ['C'])]}
I would appreciate any help.
CodePudding user response:
I find your spec odd, but I believe this implements what you were asking. I use a recursive function to find the paths from the original key to a non-zero entry, or to an entry that does not exist in dict1
.
dict1={'A': ['K', 'J'], 'C': ['A'], 'D': ['B', 'C']}
dict2={'D': {'D': '0.20','B': '0.20','C': '0.00','A': '0.06','K': '0.00','J': '0.02'},'A': {'A': '0.21', 'K': '0.00', 'J': '0.08'}}
def makepath(sub,path):
if path[-1] in dict1 and sub[path[-1]] == '0.00':
for p in dict1[path[-1]]:
yield from makepath(sub, path [p])
else:
yield path
results = {}
for tgt,sub in dict2.items():
results[tgt] = []
for p in dict1[tgt]:
for res in makepath(sub, [tgt,p]):
if len(res) == 2:
results[tgt].append(tuple(res))
else:
results[tgt].append( ((res[0],res[-1]), res[1:-1] ) )
print(results)
Output:
{'D': [('D', 'B'), (('D', 'A'), ['C'])], 'A': [('A', 'K'), ('A', 'J')]}