i have ip data as,
{'bill_source': [['U', 10], ['B', 43],['D',4]],'bill_target': [['B', 43], ['S', 17], ['U', 10]]}
and want to convert it as value, source and target key, i.e.
op={bill:[{value:"U",source:10,target:19},{value:"B",source:43,target:43},{value:"D",source:4,target:NULL},{value:"S",source:NULL,target:17}]}
i tried this with some basic python knowledge but want to improve it. below is my code,
from yaml import safe_load
data={'bill_source': [['K',20],['U', 10], ['B', 43]],'bill_target': [['B', 43], ['S', 17], ['U', 10]]}
source=[]
target=[]
kpi=[]
for key in data.keys():
if '_source' in key:
value=key.replace('_source','')
if value not in kpi:
kpi.append(value)
if '_target' in key:
value=key.replace('_target','')
if value not in kpi:
kpi.append(value)
uniq_value_key_pair=[]
a=[]
for i in data.keys():
#print(data[i])
for j in range(0,len(data[i])):
value=data[i][j]
if value not in uniq_value_key_pair:
uniq_value_key_pair.append(value)
#print(all_uniq_values)
l = uniq_value_key_pair
d = {}
for key, val in l:
d.setdefault(key, []).append(val)
uniq_values=[]
for key in d.keys():
if key not in uniq_values:
uniq_values.append(key)
final={}
f1=[]
f2=[]
print('uniq:',uniq_values)
print('kpi:',kpi)
data1=''
s1=''
final_dict={}
for main_kpi in kpi:
for key in data.keys():
if main_kpi.lower() in key.lower() and 'source' in key.lower():
s_D = {}
for key, val in data[key]:
s_D.setdefault(key, []).append(val)
for ct in range(0,len(uniq_values)):
value=uniq_values[ct]
final['value']=value
if value in s_D.keys():
sour=s_D[value]
else:
sour='NULL'
final['source']=str(sour).replace('[', '').replace(']', '')
final['target']='NULL'
s1 =str(final) '$$'
f1=s1.split('$$')
f1=list(filter(None,f1))
for key in data.keys():
if main_kpi.lower() in key.lower() and 'target' in key.lower():
s_D = {}
for key, val in data[key]:
s_D.setdefault(key, []).append(val)
for l in range(0,len(f1)):
d_val=safe_load(f1[l])
val=d_val['value']
if val in s_D.keys():
tar=str(s_D[val]).replace('[', '').replace(']', '')
else:
tar='NULL'
d_val['target']=tar
f2.append(d_val)
final_dict[main_kpi]=f2
print(final_dict)
Is there a more elegant, Pythonic solution for this task?
CodePudding user response:
Below code should do what you want:
d={'bill_source': [['U', 10], ['B', 43],['D',4]],
'bill_target': [['B', 43], ['S', 17], ['U', 10]]}
bs = dict(d['bill_source'])
bt = dict(d['bill_target'])
keys = set().union(bs.keys(), bt.keys())
op = {'bill': [{'value': i, 'source': bs.get(i), 'target': bt.get(i)} for i in keys]}
CodePudding user response:
Here's one way to do it.
First you create a list of dictionaries out from 'bill_source' and a single dictionary target from 'bill_target'.
Then you iterate over out and identify the dictionaries with matching 'value's and add target values from target (if no matching 'value' exist, set 'target' value to None).
Finally, create a list of dictionaries from what's left of target and add it to out:
out = [dict(zip(['value','source'], pair)) for pair in dct['bill_source']]
target = dict(dct['bill_target'])
for dct in out:
dct['target'] = target.pop(dct['value'], None)
op = {'bill': out [{'value': v,'source': None,'target': t} for v, t in target.items()]}
Output:
{'bill': [{'value': 'U', 'source': 10, 'target': 10},
{'value': 'B', 'source': 43, 'target': 43},
{'value': 'D', 'source': 4, 'target': None},
{'value': 'S', 'source': None, 'target': 17}]}
