I tried to created dictionary in dictionary but I struggled - python

I tried to created a get_dict function that takes a parameter as a filename and then creates and returns a dictionary which contains
key is the number of the product code and has
value is a dictionary that contains
key is a string of sizes (S, M, L, or XL), and
value is the number of the product.
enter image description here
I tried this.
def get_dict(file_name):
d={}
e={}
with open(file_name) as f:
for line in f:
line = line.strip()
alist = line.split()
e[alist[1]] = alist[2]
d[alist[0]] = e
print (d)
the output is look like this
{'4125': {'M': '4', 'L': '7', 'XL': '3'}, '5645': {'M': '4', 'L': '7', 'XL': '3'}, '7845': {'M': '4', 'L': '7', 'XL': '3'}}
but I expect that output will be like this
{4125: {'S': 1, 'M': 4}, 5645: {'L': 7}, 9874: {'S': 8}, 9875: {'M': 8}, 7845: {'S': 10, 'XL': 3}}
Text file example
7845 XL 3
4125 S 1
5645 L 7
9874 S 3
4125 M 4

def get_dict(file_name):
d={}
with open(file_name) as f:
for line in f:
line = line.strip()
alist = line.split()
if not alist[0] in d:
d[alist[0]] = {alist[1]: alist[2]}
else:
d[alist[0]].update({alist[1]: alist[2]})
print(d)
You have to update the dictionary instead of overwriting the same key value. The above solution should work.
Output -
{'7845': {'XL': '3'}, '4125': {'S': '1', 'M': '4'}, '5645': {'L': '7'}, '9874': {'S': '3'}}

Related

How Connect Lines That Have Mutual Joints

I have a list of lines like this:
Lines = ['1', '2', '3', '4', '5', '6', '7', '8']
each line has two points I and J:
LinesDetail = {
'1': {
'I': '100',
'J': '101'},
'2': {
'I': '101',
'J': '102'},
'3': {
'I': '256',
'J': '257'},
'4': {
'I': '257',
'J': '258'},
'5': {
'I': '258',
'J': '259'},
'6': {
'I': '304',
'J': '305'},
'7': {
'I': '305',
'J': '306'},
'8': {
'I': '102',
'J': '103'}}
As you see in the picture, some of these lines have mutual points
so they are connected to each other and I need to know which lines are connected to each other.
I tried while loop but I don't have the basic idea of how to solve this kind of problems.
and the result would be:
result = [["1","2","8"],["3","4","5"],["6","7"]]
All Lines Are Vertical
This is a graph problem of finding connected components. A possible interpretation is that the outer keys are labels and the inner dictionaries are the edges (and inner dict values are the nodes). If dependency is not an issue, Python has a nice API networkx that deals with graphs. Specifically, one can use the UnionFind data structure to find the disjoint subsets.
from networkx.utils.union_find import UnionFind
# reverse the label-edge mapping to get a mapping from nodes to edge labels
edges = {}
for k, d in LinesDetail.items():
for v in d.values():
edges.setdefault(v, []).append(k)
# construct union-find data structure
c = UnionFind()
for lst in edges.values():
c.union(*lst)
# get the disjoint sets as sorted lists
result = list(map(sorted, c.to_sets()))
result
# [['1', '2', '8'], ['3', '4', '5'], ['6', '7']]
Not the most optimal solution, but putting it out there since I worked on it
LinesDetail = {
'1': {
'I': '100',
'J': '101'},
'2': {
'I': '101',
'J': '102'},
'3': {
'I': '256',
'J': '257'},
'4': {
'I': '257',
'J': '258'},
'5': {
'I': '258',
'J': '259'},
'6': {
'I': '304',
'J': '305'},
'7': {
'I': '305',
'J': '306'},
'8': {
'I': '102',
'J': '103'}}
Lines = ['1', '2', '3', '4', '5', '6', '7', '8']
results = []
for item in Lines:
match_this = LinesDetail[item]['J']
list_form = []
for key, value in LinesDetail.items():
if match_this == value['I']:
results.append([item, key])
needed_list = []
for i in range(0, len(results)-1):
if results[i][1] == results[i+1][0]:
yes_list = results[i][:1] + results[i+1]
needed_list.append(yes_list)
else:
try:
if results[i][1] == results[i+2][0]:
continue
except:
needed_list.append(results[i+1])
print(needed_list)
output:
[['1', '2', '8'], ['3', '4', '5'], ['6', '7']]

Extracting a graph from a text file to a python graph

I have a text file with the following graph inside:
1: 2 3 4 5 6 2
2: 3 -4
3: 8 4
4: 5 6
5: 4 -3 8 8
6: 7 3
7: 6 -6 8 7
8:
I've been trying to extract this graph into a python graph that is formatted like the example below:
graph = {
'1': {'2': 3, '4': 5, '6': 2},
'2': {'3': -4},
'3': {'8': 4},
'4': {'5': 6},
'5': {'4': -3, '8': 8},
'6': {'7': 3},
'7': {'6': -6, '8': 7},
'8': {}
}
I am new to python and cannot figure it out. I've tried using the code below, but it just loads the graph into an array. I am unsure of how to form it into the graph example above.
graph = []
with open(fileName,'r') as file:
for line in file:
for line in line[:-1].split():
graph.append(line)
output of above code:
['1:', '2', '3', '4', '5', '6', '2', '2:', '3', '-4', '3:', '8', '4', '4:', '5', '6', '5:', '4', '-3', '8', '8', '6:', '7', '3', '7:', '6', '-6', '8', '7', '8:']
Try storing a variable and slicing every other value in the lines to create the key - value pairs to construct the dictionary, if there is nothing after the colon, it feeds and empty dictionary:
graph = []
with open(fileName,'r') as file:
for line in file:
graph.append({line.split(':')[0].replace(' ', ''): (dict(zip(line.split(': ')[1].split()[::2], map(int, line.split(': ')[1].split()[1::2]))) if ': ' in line else {})})
You can do this by splitting each line by spaces, then you can take the first element of the split and get rid of the ':' to get the start of the edge and process the rest of the entries two at a time, the first being the other node in the edge and the entry being the number. Then you can just put each intermediate result into a dictionary:
graph = {}
with open(fileName,'r') as file:
for line in file:
s = line.split(' ')
u = s[0].strip(':')
graph[u] = {}
for i in range(1, len(s), 2):
v = s[i]
c = int(s[i + 1])
graph[u][v] = c

How to reload text file into JSON after text file is edited in Python?

I want to reload my JSON after my text file is updated by reopening the text file.
import json
with open('np.txt') as np:
np_data = np.read()
np_list=json.loads(np_data)
def reopen_file():
print("reloading")
with open('np.txt') as np:
np_data = np.read()
np_list=json.loads(np_data)
y=1
while(y==1):
#np.flush()
#reopen_file()
x=input("input: ")
print("your input is" +x)
if(int(x)==1):
print(np_list)
y=input("continue?: ")
reopen_file()
print(np_list)
OUTPUT:
I update the text file before entering the value for 'y'(continue?), but the output remains the same. (I am editing the file manually)
np.txt:
{"a":"1",
"b":"2",
"c":"3",
"d":"4",
"e":"5",
"f":"6",
"g":"7",
"h":"8",
"i":"9"}
As I already commented, your code is not actually updating the same np_list you are using. A quick and dirty example to show this is just adding a print(np_list) at the end of reopen_file:
input: 1
your input is1
{'e': '5', 'b': '2', 'd': '4', 'f': '5', 'c': '3', 'a': '1', 'h': '8', 'i': '9', 'g': '7'}
continue?: 1
reloading
{'e': '5', 'b': '2', 'd': '4', 'f': '6', 'c': '3', 'a': '1', 'h': '8', 'i': '9', 'g': '7'}
{'e': '5', 'b': '2', 'd': '4', 'f': '5', 'c': '3', 'a': '1', 'h': '8', 'i': '9', 'g': '7'}
This solution works fine:
import json
def reopen_file():
with open('np.txt') as np:
np_data = np.read()
return json.loads(np_data)
np_list=reopen_file()
y=1
while(y==1):
#np.flush()
#reopen_file()
x=input("input: ")
print("your input is" +x)
if(int(x)==1):
print(np_list)
y=int(input("continue?: "))
np_list = reopen_file()
Which outputs:
Python-reload-file> python test.py
input: 1
your input is1
{'d': '4', 'b': '2', 'f': '5', 'h': '8', 'e': '5', 'a': '1', 'c': '3', 'i': '9', 'g': '7'}
continue?: 1
input: 1
your input is1
{'d': '4', 'b': '2', 'f': '6', 'h': '8', 'e': '5', 'a': '1', 'c': '3', 'i': '9', 'g': '7'}
continue?:
np_list is declared as a global variable that you can't overwrite without using the global keyword. Simplified example:
a = 3
def change_a():
a = 4
print("inside:", a)
print("outside:", a)
change_a()
print("outside after:", a)
output:
outside: 3
inside: 4
outside after: 3
example using the global keyword: (don't do this if you have other options like making a class)
a = 3
def change_a():
global a
a = 4
print("inside:", a)
print("outside:", a)
change_a()
print("outside after:", a)
output:
outside: 3
inside: 4
outside after: 4
Another small hint about how you read your json file: instead of doing
import json
with open('np.txt') as np:
np_data = np.read()
np_list=json.loads(np_data)
you can just
with open("np.txt") as np:
np_list = json.load(np)

How to create nested dictionary without losing data?

I have the file which contains distance values for a set of nodes in matrix form. I extracted those values and want to save them in a nested dictionary.
I already tried, but my dictionary contains only values from the last iteration.
d={}
i, j = 0,0
for f in tmp:
for k in range(3,len(f),3):
d[nodes[i]] = {}
d[nodes[i]][nodes[j]]= f[k-2]+f[k-1]
j += 1
i += 1
j = 0
return d
d={'A': {'P': '5'},
'B': {'P': '3'},
'C': {'P': '6'},
'D': {'P': '5'},
'E': {'P': '3'},
'F': {'P': '33'},
'G': {'P': '21'},
'H': {'P': '39'},
'I': {'P': '4'}}
But d should contain:
d={"A":{"A":5,"B":6, "C":7, "D":8, "E":9, "F":10, "G":11;"H":12, "I":13},
"B":{"A":3,"B":4, "C":5, "D":8, "E":9, "F":14, "G":11;"H":12,
"I":16}},.....
You're re-initializing the second-level dict each iteration of your inner loop. That is what is causing it to "lose data".
Instead, you could use a defaultdict:
from collections import defaultdict
d = defaultdict(dict)
i, j = 0,0
for f in tmp:
for k in range(3,len(f),3):
d[nodes[i]][nodes[j]]= f[k-2]+f[k-1]
j += 1
i += 1
j = 0
return d

python string tokenization - custom lexer?

I have a string like:
<number>xx<->a<T>b<F>c<F>d<F>e<F>f<F>g<T>h<F>i<F>
How can I efficiently parse this string so that i.e.
xx has a value of null
a has a value of 1
b has a value of
0
You can parse that with Regular Expressions. We first remove the initial <word> at the start of the string, if it exists, and then look for pairs of word<word>, saving them into key,value pairs in a dictionary using the codes dictionary to convert _, F, T, to null, 0, 1.
import re
s = '<number>xx<->a<T>b<F>c<F>d<F>e<F>f<F>g<T>h<F>i<F>'
m = re.match(r'<(\w*?)>', s)
if m:
head = m.group(1)
s = s[m.end():]
print(head)
else:
print('No head group')
codes = {'-': 'null', 'F': '0', 'T': '1'}
pat = re.compile(r'(\w*?)<([-\w]*?)>')
out = {k: codes[v] for k, v in pat.findall(s)}
print(out)
output
number
{'xx': 'null', 'a': '1', 'b': '0', 'c': '0', 'd': '0', 'e': '0', 'f': '0', 'g': '1', 'h': '0', 'i': '0'}

Categories

Resources