Why does the loop behave differently in only one iteration?

I have this code:

gs = open("graph.txt", "r") gp = gs.readline() gp_splitIndex = gp.find(" ") gp_nodeCount = int(gp[0:gp_splitIndex]) gp_edgeCount = int(gp[gp_splitIndex+1:-1]) matrix = [] # predecare the array for i in range(0, gp_nodeCount): matrix.append([]) for y in range(0, gp_nodeCount): matrix[i].append(0) for i in range(0, gp_edgeCount-1): gp = gs.readline() gp_splitIndex = gp.find(" ") # get the index of space, dividing the 2 numbers on a row gp_from = int(gp[0:gp_splitIndex]) gp_to = int(gp[gp_splitIndex+1:-1]) matrix[gp_from][gp_to] = 1 print matrix 

The graph.txt file contains the following:

 5 10 0 1 1 2 2 3 3 4 4 0 0 3 3 1 1 4 4 2 2 0 

The first two numbers tell me that GRAPH has 5 nodes and 10 edges. The following pairs of pairs show edges between nodes. For example, β€œ1 4” means the line between node 1 and 4.

The problem is that the output should be as follows:

 [[0, 1, 0, 1, 0], [0, 0, 1, 0, 1], [1, 0, 0, 1, 0], [0, 1, 0, 0, 1], [1, 0, 1, 0, 0]] 

But instead, I get the following:

 [[0, 1, 0, 1, 0], [0, 0, 1, 0, 1], [0, 0, 0, 1, 0], [0, 1, 0, 0, 1], [1, 0, 1, 0, 0]] 

Only one number is different, and I do not understand why this is happening. Edge "3 1" is missing. Can someone explain where the problem is?

+6
source share
4 answers

Matthias has it; you do not need edgeCount - 1 , since the range function does not include the final value in the iteration.

There are several other things you can do to clear your code:

  • The with statement is preferred for opening files, as it automatically closes them for you.
  • You do not need to invoke find and manual slice, split already does what you want.
  • You can directly convert and assign a pair of numbers using a generator expression and iterative unpacking
  • You can only call range with a finite value, beginning 0 implicitly.
  • The multiplication operator is convenient for initializing lists.

With all these changes:

 with open('graph.txt', 'r') as graph: node_count, edge_count = (int(n) for n in graph.readline().split()) matrix = [[0]*node_count for _ in range(node_count)] for i in range(edge_count): src, dst = (int(n) for n in graph.readline().split()) matrix[src][dst] = 1 print matrix # [[0, 1, 0, 1, 0], [0, 0, 1, 0, 1], [1, 0, 0, 1, 0], [0, 1, 0, 0, 1], [1, 0, 1, 0, 0]] 
+3
source

Change for i in range(0, gp_edgeCount-1): to

 for i in range(0, gp_edgeCount): 

The range() function is already performing the -1 operation. range(0,3) "==" [0,1,2]

And it’s not that the β€œ3 1” is missing, it’s the β€œ2 0” lack, and this is the last edge. Matrices start at 0.

+5
source

Just to preserve your code and style, of course, this can be much more readable:

 gs = open("graph.txt", "r") gp = gs.readline() gp_splitIndex = gp.split(" ") gp_nodeCount = int(gp_splitIndex[0]) gp_edgeCount = int(gp_splitIndex[1]) matrix = [] # predecare the array for i in range(0, gp_nodeCount): matrix.append([]) for y in range(0, gp_nodeCount): matrix[i].append(0) for i in range(0, gp_edgeCount): gp = gs.readline() gp_Index = gp.split(" ") # get the index of space, dividing the 2 numbers on a row gp_from = int(gp_Index[0]) gp_to = int(gp_Index[1]) matrix[gp_from][gp_to] = 1 print matrix 

It is the last instance that is not used ... 2 0 from your file. Thus missed 1. Have a nice day!

+2
source

Other answers are correct, another version is similar to that of tzaman:

 with open('graph.txt', mode='r') as txt_file: lines = [l.strip() for l in txt_file.readlines()] number_pairs = [[int(n) for n in line.split(' ')] for line in lines] header = number_pairs[0] edge_pairs = number_pairs[1:] num_nodes, num_edges = header edges = [[0] * num_nodes for _ in xrange(num_nodes)] for edge_start, edge_end in edge_pairs: edges[edge_start][edge_end] = 1 print edges 
0
source

Source: https://habr.com/ru/post/1012994/


All Articles