Incorrect output dictionary from user's input - python

I need output to be in the form
{0: {1:11,2:13}, 1: {0:11,3:14}}
But it comes out to
{0: {1:['11'],2:['13']}, 1: {0:['11'],3:['14']}}
using this
graph = {}
N,w = map(int,raw_input().split())
# print N, w
for x in range(0,C):
i,j,c = raw_input().split()
graph.setdefault(int(i), {}).setdefault(int(j),[]).append(w)
print graph
on INPUT
1st line: Ignore N=4, while C=4 is the number of lines.
2nd line: i,j are vertices, w is the edge weight.
4 4
0 1 11
0 2 13
1 0 11
1 3 14

You are setting lists as values inside your nested dictionary in the following line -
graph.setdefault(int(i), {}).setdefault(int(j),[]).append(w)
This is why you are getting values inside list, if you are 100% sure that the key:value pairs inside the nested dictionary would always be unique, then you can simply set the value to the key. Example -
graph.setdefault(int(i), {})[int(j)] = w

Related

Python - find lowest value across dictionaries

I have a dictionary that is structured as follows:
MSE = {}
MSE[1] = {}
MSE[2] = {}
MSE[3] = {}
That is, the dictionary itself consists of a number of dictionaries. These look as follows:
MSE[1][1] = 5
MSE[1][2] = 3
MSE[1][2] = 7
MSE[2][1] = 4
MSE[2][2] = 3
MSE[2][2] = 7
MSE[3][1] = 1
MSE[3][2] = 1
MSE[3][2] = 2
I want to find the lowest of these values across all the different dictionaries. How do I do that?
The values of a dictionary d:
d.values()
The minimum of an iterable, like the result of .values() of a dictionary:
min(d.values())
So, you want the minimum of all the minimums for each dictionary in some dictionary (say, MSE):
min(min(d.values()) for d in MSE.values())
This loops over all of the values in MSE, which in your case are dictionaries. It finds the minimum value for each and then takes the minimum out of all of those.
You can do it like this:
minm = min([min(i.values()) for i in MSE.values()])

Find the total amount of characters in a list

I'm kind of stuck on an Edabit Challenge (Link: https://edabit.com/challenge/S9KCN5kqoDbhNdKh5 ),
and the objective is to basically find the total amount of characters in a list (all of the values are strings) and return that value.
Some examples are provided:
count_characters([
"###",
"###",
"###"
]) ➞ 9
count_characters([
"22222222",
"22222222",
]) ➞ 16
count_characters([
"------------------"
]) ➞ 18
count_characters([]) ➞ 0
count_characters(["", ""]) ➞ 0
My current code to achieve the goal is:
def count_characters(lst):
print(lst) #I print the list
count = 0 #Setting my count var to 0
for item in lst: #Using a for loop to iterate through the list's values
count += len(lst) #Getting the length of each value and adding it to the variable 'count'
print(len(lst)) #I also print the length of each value
print(count) #Outside the for loop, I print the count variable
return count #Then I return it
(There are multiple tests to check if the entire function works btw)
When I ran the code, this is what the console outputs:
['###', '###', '###']
3
3
3
9
Test Passed
['22222222', '22222222']
2
2
4
FAILED: 4 should equal 16
ERROR: Traceback:
in <module>
File "./frameworks/python/cw-2.py", line 28, in assert_equals
expect(actual == expected, message, allow_raise)
File "./frameworks/python/cw-2.py", line 18, in expect
raise AssertException(message)
cw-2.AssertException: 4 should equal 16
I don't understand why the code did not find the length of the 2nd test, but worked for the 1st test.
Thank you
A very minor mistake...in the loop
for item in lst:
count+=len(item)
You are doing
for item in lst:
count+=len(lst)
As in the 1st case, both length of list & length of each element is 3, the code gave the desired output but not for the 2nd case

How to find the negative weight between two adjacent nodes in python

Hi i have a big text file with format like this:
1 3 1
2 3 -1
5 7 1
6 1 -1
3 2 -1
the first column is the starting node, the second column the ending node and the third column shows the sign between two nodes. So i have positive and negative signs.
Im reading the graph with the code below:
G = nx.Graph()
G = nx.read_edgelist('network.txt', delimiter='\t', nodetype=int, data=(('weight', int),))
print(nx.info(G))
I also found a function to find the neighbors of a specific node:
list1 = list(G.neigbors(1))
So i have a list with the adjacency nodes of node 1. How can a find the sign between the node 1 and each adjacency node? (For example that edge between 1-3 has sign 1, the edge 1-5 has sign -1 etc)
An example for node 1:
n_from = 1
for n_to in G.neighbors(n_from):
sign = G[n_from][n_to]['weight']
print('edge from {} to {} has sign {}'.format(
n_from, n_to, sign))
which prints, for the example input you gave:
edge from 1 to 3 has sign 1
edge from 1 to 6 has sign -1
A similar approach, treating G[n_from] as a dict:
n_from = 1
for n_to, e_data in G[n_from].items():
sign = e_data['weight']
# then print
You can alternatively use Graph.get_edge_data, as such:
e_data = G.get_edge_data(n_from, n_to)
sign = e_data.get('weight')

python changes values of list

I am fairly new to Python so please be patient, this is probably simple. I am trying to build an adjacency list representation of a graph. In this particular representation I decided to use list of lists where the first value of each sublist represents the tail node and all other values represent head nodes. For example, the graph with edges 1->2, 2->3, 3->1, 1->3 will be represented as [[1,2,3],[2,3],[3,1]].
Running the following code on this edge list, gives a problem I do not understand.
The edge list (Example.txt):
1 2
2 3
3 1
3 4
5 4
6 4
8 6
6 7
7 8
The Code:
def adjacency_list(graph):
graph_copy = graph[:]
g_tmp = []
nodes = []
for arc in graph_copy:
choice_flag_1 = arc[0] not in nodes
choice_flag_2 = arc[1] not in nodes
if choice_flag_1:
g_tmp.append(arc)
nodes.append(arc[0])
else:
idx = [item[0] for item in g_tmp].index(arc[0])
g_tmp[idx].append(arc[1])
if choice_flag_2:
g_tmp.append([arc[1]])
nodes.append(arc[1])
return g_tmp
# Read input from file
g = []
with open('Example.txt') as f:
for line in f:
line_split = line.split()
new_line = []
for element in line_split:
new_line.append(int(element))
g.append(new_line)
print('File Read. There are: %i items.' % len(g))
graph = adjacency_list(g)
During runtime, when the code processes arc 6 7 (second to last line in file), the following lines (found in the else statement) append 7 not only to g_tmp but also to graph_copy and graph.
idx = [item[0] for item in g_tmp].index(arc[0])
g_tmp[idx].append(arc[1])
What is happening?
Thank you!
J
P.S. I'm running Python 3.5
P.P.S. I also tried replacing graph_copy = graph[:] with graph_copy = list(graph). Same behavior.
The problem is in the lines
if choice_flag_1:
g_tmp.append(arc)
When you append arc, you are appending a shallow copy of the inner list. Replace with a new list like so
if choice_flag_1:
g_tmp.append([arc[0],arc[1]])

python print multiple value of key in different lines

I have a dictionary with each key containing multiple values (list):
one = [1,2,3]
two = [1,2,3]
three= [1,2,3]
It was obtained with the following line of code:
output_file.write('{0}\t{1}\n'.format(key,"\t".join(value)))
So my final printed output looks like this:
one 1 2 3
two 1 2 3
three 1 2 3
My goal now is to have the output looking like this instead:
one 1
one 2
one 3
two 1
two 2
…
Any tips?
You can add the key itself as delimiter
#key = "one"
#value = ['1','2','3']
print(key+'\t'+'\n{0}\t'.format(key).join(value))
output
one 1
one 2
one 3
You could do this with nested for-loops:
for key, value_list in my_dict.iteritems():
for value in value_list:
output_file.write("{}\t{}\n".format(key, value))
this may also work...
#key = "one"
#value = ['1','2','3']
print '\n'.join(map(lambda i: key+'\t'+str(i), value))

Categories

Resources