Storing list into dictionary from excel - python

I have stored data into list from excel but now I want to store it into dictionary.
here is the excel
in list it giving output like this.
[['Nodeb_IN_New', 107, 'class-default', 'mobility-platinum', 'h1', 7, 'dscp-fc-map', ['ef']], ['', 107, '', 'mobility-gold-new', 'h2', 5, 'dscp-fc-map', ['af41']], ['', 107, '', 'mobility-silver-new', 'l1', 4, 'dscp-fc-map', ['af11', 'af21', 'af31']], ['Nokia_SRAN_S1-MME_X2_IN', 102, '', 'Nokia_SRAN_mobility_platinum', 'h1', 7, 'dscp-fc-map', ['ef', 'nc1']]]
same I want into dictionary. I have written this code
def myfun(list):
list = list
res=dict()
qos=None
for row in list:
if row[0]=="":
res[qos]['b']=row[1]
res[qos]['c']=row[2]
res[qos]['d']=row[3]
res[qos]['e']=row[4]
res[qos]['f']=row[5]
res[qos]['g']=row[6]
res[qos]['h']=row[7]
else:
qos=row[0]
res[qos]=dict()
res[qos]['b']=row[1]
res[qos]['c']=row[2]
res[qos]['d']=row[3]
res[qos]['e']=row[4]
res[qos]['f']=row[5]
res[qos]['g']=row[6]
res[qos]['h']=row[7]
but it is giving output like this.
{'Nodeb_IN_New': {
'b': 107, 'c': '', 'd': 'mobility-silver-new',
'e': 'l1', 'f': 4, 'g': 'dscp-fc-map',
'h': ['af11', 'af21', 'af31']
},
'Nokia_SRAN_S1-MME_X2_IN': {
'b': 102, 'c': '', 'd': 'Nokia_SRAN_mobility_platinum', 'e': 'h1', 'f': 7, 'g': 'dscp-fc-map', 'h': ['ef', 'nc1']}}
under 'Nodeb_IN_New' I want all the 3 lines(from excel).

The reason your code isn't working, is that when you are going through the rows and inserting them into the target dictionary res, you are also setting the value to a sub-dictionary, and in this sub-dictionary, the rows will always go under the same key ‘b’, ‘c’, ‘d’, etc., in other words, the rows at the bottom are overwriting the rows at top, leaving you just the 3rd row for Nodeb_IN_New.
Another way would be to set the value to a list, and go through the rows, append them to this list if they belong to the same qos, here's the code:
# Original excel sheet in a list
raw_list = [
['Nodeb_IN_New', 107, 'class-default', 'mobility-platinum', 'h1', 7, 'dscp-fc-map', ['ef']],
['', 107, '', 'mobility-gold-new', 'h2', 5, 'dscp-fc-map', ['af41']],
['', 107, '', 'mobility-silver-new', 'l1', 4, 'dscp-fc-map', ['af11', 'af21', 'af31']],
['Nokia_SRAN_S1-MME_X2_IN', 102, '', 'Nokia_SRAN_mobility_platinum', 'h1', 7, 'dscp-fc-map', ['ef', 'nc1']]
]
result_dict = {}
# title, will be used as key in the result_dict
title = ""
# Loop through the input list
for row in raw_list:
# If the first value is not empty, replace the title with this new value
if row[0] != "":
# update title
title = row[0]
# Insert into the dictionary, and give an empty list as a place holder,
# later we can append to this list
result_dict[title] = []
# At this stage we can append the rest of the input row to the dictionary value
result_dict[title].append(row[1:])
print("Result dict: ")
for (key, value) in result_dict.items():
print("Key: {}".format(key))
for row in value:
print(" {}".format(row))
And here's the output of the code above:
Key: Nodeb_IN_New
[107, 'class-default', 'mobility-platinum', 'h1', 7, 'dscp-fc-map', ['ef']]
[107, '', 'mobility-gold-new', 'h2', 5, 'dscp-fc-map', ['af41']]
[107, '', 'mobility-silver-new', 'l1', 4, 'dscp-fc-map', ['af11', 'af21', 'af31']]
Key: Nokia_SRAN_S1-MME_X2_IN
[102, '', 'Nokia_SRAN_mobility_platinum', 'h1', 7, 'dscp-fc-map', ['ef', 'nc1']]

try this code :
import json
l=[['Nodeb_IN_New', 107, 'class-default', 'mobility-platinum', 'h1', 7, 'dscp-fc-map', ['ef']], ['', 107, '', 'mobility-gold-new', 'h2', 5, 'dscp-fc-map', ['af41']], ['', 107, '', 'mobility-silver-new', 'l1', 4, 'dscp-fc-map', ['af11', 'af21', 'af31']], ['Nokia_SRAN_S1-MME_X2_IN', 102, '', 'Nokia_SRAN_mobility_platinum', 'h1', 7, 'dscp-fc-map', ['ef', 'nc1']]]
def myfun(list):
res=dict()
qos=None
d={}
li=[]
for row in list:
if row[0]=="":
res[qos]=dict()
res[qos]['b']=row[1]
res[qos]['c']=row[2]
res[qos]['d']=row[3]
res[qos]['e']=row[4]
res[qos]['f']=row[5]
res[qos]['g']=row[6]
res[qos]['h']=row[7]
else:
qos=row[0]
res[qos]=dict()
res[qos]['b']=row[1]
res[qos]['c']=row[2]
res[qos]['d']=row[3]
res[qos]['e']=row[4]
res[qos]['f']=row[5]
res[qos]['g']=row[6]
res[qos]['h']=row[7]
x = res.keys()
keylist = []
keylist.extend(iter(x))
if keylist[0] in d.keys():
d[keylist[0]].append(res[qos])
else:
d[keylist[0]] = []
d[keylist[0]].append(res[qos])
print(d)
print(json.dumps(d))
myfun(l)
output:
{'Nokia_SRAN_S1-MME_X2_IN': [{'d': 'Nokia_SRAN_mobility_platinum', 'f': 7, 'e': 'h1', 'b': 102, 'c': '', 'h': ['ef', 'nc1'], 'g': 'dscp-fc-map'}], 'Nodeb_IN_New': [{'d': 'mobility-platinum', 'f': 7, 'e': 'h1', 'b': 107, 'c': 'class-default', 'h': ['ef'], 'g': 'dscp-fc-map'}, {'d': 'mobility-gold-new', 'f': 5, 'e': 'h2', 'b': 107, 'c': '', 'h': ['af41'], 'g': 'dscp-fc-map'}, {'d': 'mobility-silver-new', 'f': 4, 'e': 'l1', 'b': 107, 'c': '', 'h': ['af11', 'af21', 'af31'], 'g': 'dscp-fc-map'}]}
result in json to be readable :
{
"Nokia_SRAN_S1-MME_X2_IN": [
{
"d": "Nokia_SRAN_mobility_platinum",
"f": 7,
"e": "h1",
"b": 102,
"c": "",
"h": [
"ef",
"nc1"
],
"g": "dscp-fc-map"
}
],
"Nodeb_IN_New": [
{
"d": "mobility-platinum",
"f": 7,
"e": "h1",
"b": 107,
"c": "class-default",
"h": [
"ef"
],
"g": "dscp-fc-map"
},
{
"d": "mobility-gold-new",
"f": 5,
"e": "h2",
"b": 107,
"c": "",
"h": [
"af41"
],
"g": "dscp-fc-map"
},
{
"d": "mobility-silver-new",
"f": 4,
"e": "l1",
"b": 107,
"c": "",
"h": [
"af11",
"af21",
"af31"
],
"g": "dscp-fc-map"
}
]
}

Related

Python3 Merge two dictionaries based on sub dictionaries keys w/o for loop

Maybe this is impossible but without a for loop through each key in a given dictionary merge the two based on the key in the dictionary
Given :
dict1 = { 'APPL' : { 'cp': 1, 'sed': 'bull'}, 'BAC' : { 'cp': 1, 'sed': 'bull'}}
dict2 = { 'APPL' : { 'tp': 100}}
dict3 = dict1 | dict2 ## python ≥3.9 only
print(dict3)
{'APPL': {'tp': 100}, 'BAC': {'cp': 1, 'sed': 'bull'}}
dict1.update(dict2)
print(dict1)
{'APPL': {'tp': 100}, 'BAC': {'cp': 1, 'sed': 'bull'}}
Desired output
{'APPL': {'tp': 100,'cp': 1, 'sed': 'bull'}, 'BAC': {'cp': 1, 'sed': 'bull'}}
I can do it now with a for loop , just wondering if there is a more elegant solution
Do:
dict1 = {'APPL': {'cp': 1, 'sed': 'bull'}, 'BAC': {'cp': 1, 'sed': 'bull'}}
dict2 = {'APPL': {'tp': 100}}
res = {key: {**value, **dict2.get(key, {})} for key, value in dict1.items()}
print(res)
Output
{'APPL': {'cp': 1, 'sed': 'bull', 'tp': 100}, 'BAC': {'cp': 1, 'sed': 'bull'}}
No, this isn't possible without iteration. You could use a custom joiner function and then reduce a list of dictionaries however:
data = [{'BAC': {'a': 40}, 'XYZ': {'c': 81, 'b': 16}, 'ABC': {'b': 85}},
{'APPL': {'b': 55},
'BAC': {'b': 16, 'f': 59},
'ABC': {'d': 9, 'c': 43},
'XYZ': {'b': 82}},
{'ABC': {'b': 43, 'c': 35},
'APPL': {'f': 17, 'a': 1, 'd': 16},
'BAC': {'f': 35, 'a': 1},
'XYZ': {'a': 2, 'c': 55}},
{'BAC': {'f': 4, 'd': 87},
'XYZ': {'d': 31, 'f': 92},
'APPL': {'b': 18, 'a': 74, 'c': 69}},
{'XYZ': {'d': 84, 'f': 49},
'ABC': {'d': 88, 'a': 82, 'f': 96},
'APPL': {'a': 23},
'BAC': {'b': 40}},
{'BAC': {'c': 88, 'd': 38},
'APPL': {'c': 48, 'b': 30},
'ABC': {'d': 95, 'b': 38},
'XYZ': {'d': 90, 'a': 5}}]
def join_dict(d1, d2):
result = {k: {**d1[k], **d2[k]} for k in d1}
result.update({k: {**d1[k], **d2[k]} for k in d2})
return result
>>> import functools
>>> functools.reduce(join_dict, data)
{'XYZ': {'a': 39, 'f': 78, 'c': 42, 'd': 30, 'b': 24},
'ABC': {'c': 22, 'f': 69, 'a': 8, 'b': 51, 'd': 70},
'APPL': {'d': 19, 'b': 35, 'a': 6, 'f': 33, 'c': 64},
'BAC': {'f': 97, 'c': 38, 'd': 1, 'b': 63, 'a': 91}}
Of course, this will overwrite any common values in the sub-dictionaries. Assuming that isn't an issue for you, this should work fine as a "more elegant solution".

exact string matching in two lists in python

I need to match two lists one with characters and other with words
My current code is:
char_list=['G','UH','D','S', 'ER', 'M', 'AY', 'S', 'EH', 'L', 'F', 'B', 'AE', 'NG', 'K']
word_list=['GUHD','MAORNIHNG','SER','MAY','SEHLF','BAENGK']
for word_p in word_list:
scores = {}
p_s=""
if str(word_p) != "NULL":
print(word_p)
for j in char_list:
if len(word_p) == len(p_s):
print("word end")
for i in scores.keys():
char_list.remove(i)
break
else:
if j in word_p:
p_s=p_s+j
scores[j] = gop_scores.get(str(j))#this returns an integer value corresponding to char
sep_scores[str(word_p)] = scores
print(sep_scores)
The current output is:-
*{'GUHD': {'G': 100.0, 'UH': 18.142809657631524, 'D': 61.62375099467158}, 'MAORNIHNG': {'M': 100.0, 'NG': 43.40719714138942}, 'SER': {'S': 100.0, 'ER': 100.0}, 'MAY': {'M': 100.0, 'AY': 100.0}, 'SEHLF': {'S': 100.0, 'EH': 89.72295878282416, 'L': 100.0, 'F': 0.0}, 'BAENGK': {'B': 7.166608749080874, 'AE': 68.10287800038276, 'NG': 43.40719714138942, 'K': 100.0}}}*
Note
Everything seems fine but there is no exact matching char for MAORNIHNG and still i am getting{'M','NG'}, I want the MAORNIHNG value to be empty
expected output
*{'GUHD': {'G': 100.0, 'UH': 18.142809657631524, 'D': 61.62375099467158}, 'MAORNIHNG': {}, 'SER': {'S': 100.0, 'ER': 100.0}, 'MAY': {'M': 100.0, 'AY': 100.0}, 'SEHLF': {'S': 100.0, 'EH': 89.72295878282416, 'L': 100.0, 'F': 0.0}, 'BAENGK': {'B': 7.166608749080874, 'AE': 68.10287800038276, 'NG': 43.40719714138942, 'K': 100.0}}}*
The 'MAORNIHNG' value should be empty dict
You just need to make sure that the dictionary keys form the entire word, and if not return an empty dict, you can do this by joining them and comparing:
char_list=['G','UH','D','S', 'ER', 'M', 'AY', 'S', 'EH', 'L', 'F', 'B', 'AE', 'NG', 'K']
word_list=['GUHD','MAORNIHNG','SER','MAY','SEHLF','BAENGK']
sep_scores={}
for word_p in word_list:
scores = {}
p_s=""
if str(word_p) != "NULL":
print(word_p)
for j in char_list:
if len(word_p) == len(p_s):
print("word end")
for i in scores.keys():
char_list.remove(i)
break
else:
if j in word_p:
p_s=p_s+j
scores[j] = 1#this returns an integer value corresponding to char
if ''.join(scores.keys()) == word_p:
sep_scores[str(word_p)] = scores
else:
sep_scores[str(word_p)] = {}
print(sep_scores)
>>> {'GUHD': {'G': 1, 'UH': 1, 'D': 1}, 'MAORNIHNG': {}, 'SER': {'S': 1, 'ER': 1}, 'MAY': {'M': 1, 'AY': 1}, 'SEHLF': {'S': 1, 'EH': 1, 'L': 1, 'F': 1}, 'BAENGK': {'B': 1, 'AE': 1, 'NG': 1, 'K': 1}}

How can i make a dictionary from txt file in python

I have get this txt file
A:{A:0, B:6, C:4, D:3, E:0, F:0, G:0}
B:{A:6, B:0, C:2, D:0, E:4, F:0, G:0}
C:{A:4, B:2, C:0, D:2, E:0, F:8, G:0}
D:{A:3, B:0, C:2, D:0, E:3, F:0, G:0}
E:{A:0, B:4, C:0, D:3, E:0, F:7, G:6}
F:{A:0, B:0, C:8, D:0, E:7, F:0, G:6}
G:{A:0, B:0, C:0, D:0, E:6, F:6, G:0}
titles = []
with open("graph.txt", "r") as file:
for line in file:
column=line.split(":")
title=column[0]
titles.append(title)
i need to make dictionaries for each title which i got like A,B,C
Format each line properly and you can use ast.literal_eval. I used regex to find each key and replace it with the same key surrounded by quotes.
import ast
import re
KEY_PATTERN = re.compile(r'(\w+?):')
dics = []
with open('graph.txt') as f:
for line in f:
line = line.strip()
if line:
dic_str = "{" + KEY_PATTERN.sub(r'"\g<1>":', line) + "}"
dics.append(ast.literal_eval(dic_str))
print(dics)
Can be shorter (though harder to read):
import ast
import re
KEY_PATTERN = re.compile(r'(\w+?):')
with open('graph.txt') as f:
dics = [ast.literal_eval("{" + KEY_PATTERN.sub(r'"\g<1>":', line) + "}") for line in f if line.strip()]
print(dics)
Output:
[{'A': {'A': 0, 'B': 6, 'C': 4, 'D': 3, 'E': 0, 'F': 0, 'G': 0}}, {'B': {'A': 6, 'B': 0, 'C': 2, 'D': 0, 'E': 4, 'F': 0, 'G': 0}}, {'C': {'A': 4, 'B': 2, 'C': 0, 'D': 2, 'E': 0, 'F': 8, 'G': 0}}, {'D': {'A': 3, 'B': 0, 'C': 2, 'D': 0, 'E':3, 'F': 0, 'G': 0}}, {'E': {'A': 0, 'B': 4, 'C': 0, 'D': 3, 'E': 0, 'F': 7, 'G': 6}}, {'F': {'A': 0, 'B': 0, 'C': 8, 'D': 0, 'E': 7, 'F': 0, 'G': 6}}, {'G': {'A': 0, 'B': 0, 'C': 0, 'D': 0, 'E': 6, 'F': 6, 'G': 0}}]
If you want the result to be just one dict than change:
dics = []
# and
dics.append(ast.literal_eval(dic_str))
to
dics = {}
# and
dics.update(ast.literal_eval(dic_str))
This can be achieved with the following sample:
import re
titles = []
with open("graph.txt", "r") as file:
for line in file:
if ':' in line:
title=re.match(r"^(.*?):", line).groups()[0]
dict_str= re.match("^.*?\{(.*?)\}", line).groups()[0]
dictionary = {key:value for (key,value) in (item.strip().split(':') for item in dict_str.split(','))}
titles.append({title: dictionary})
for item in titles:
print(item)
This will produce output like:
{'A': {'A': '0', 'C': '4', 'B': '6', 'E': '0', 'D': '3', 'G': '0', 'F': '0'}}
{'B': {'A': '6', 'C': '2', 'B': '0', 'E': '4', 'D': '0', 'G': '0', 'F': '0'}}
{'C': {'A': '4', 'C': '0', 'B': '2', 'E': '0', 'D': '2', 'G': '0', 'F': '8'}}
{'D': {'A': '3', 'C': '2', 'B': '0', 'E': '3', 'D': '0', 'G': '0', 'F': '0'}}
{'E': {'A': '0', 'C': '0', 'B': '4', 'E': '0', 'D': '3', 'G': '6', 'F': '7'}}
{'F': {'A': '0', 'C': '8', 'B': '0', 'E': '7', 'D': '0', 'G': '6', 'F': '0'}}
{'G': {'A': '0', 'C': '0', 'B': '0', 'E': '6', 'D': '0', 'G': '0', 'F': '6'}}

python recursively sort all nested iterable

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

How to sort a complex nested dictionary to a nested list

What is the best way to sort a nested dictionary in Python 2.6 by value? I would like to sort by the length of the inner dictionary followed by the inner dictionary with the largest value. For example:
d = {1: {'AA': {'a': 100, 'b': 1, 'c': 45}},
2: {'AA': {'c': 2}},
3: {'BB': {'d': 122, 'a': 4, 't': 22, 'r': 23, 'w': 12}},
4: {'CC': {'y': 12, 'g': 15, 'b': 500}}}
The desired solution is a nested list:
lst = [[3, 'BB', {'d': 122, 'a': 4, 't': 22, 'r': 23, 'w': 12}],
[4, 'CC', {'y': 12, 'g': 15, 'b': 500}],
[1, 'AA', {'a': 100, 'b': 1, 'c': 45}],
[2, 'AA', {'c': 2}]]
With your corrected data-structure:
d = {1: {'AA': {'a': 100, 'b': 1, 'c': 45}},
2: {'AA': {'c': 2}},
3: {'BB': {'d': 122, 'a': 4, 't': 22, 'r': 23, 'w': 12}},
4: {'CC': {'y': 12, 'g': 15, 'b': 500}}}
def sortkey(x):
num,d1 = x
key,d2 = d1.items()[0] #Some may prefer `next(d.iteritems())`
return len(d2),max(d2.values())
exactly_how_you_want_it = [([k] + v.keys() + v.values()) for k,v in
sorted(d.items(),reverse=True,key=sortkey)]
for item in exactly_how_you_want_it:
print item
results:
[3, 'BB', {'a': 4, 'r': 23, 'd': 122, 'w': 12, 't': 22}]
[4, 'CC', {'y': 12, 'b': 500, 'g': 15}]
[1, 'AA', {'a': 100, 'c': 45, 'b': 1}]
[2, 'AA', {'c': 2}]

Categories

Resources