2016-12-08 6 views
6

mam ten kod:Dlaczego cykl zachowuje się inaczej w jednej iteracji?

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 

Plik ten zawiera graph.txt:

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

Pierwsze dwie liczby mówią mi, że wykres ma 5 węzłów i 10 krawędzi. Następujące pary liczb pokazują krawędzie między węzłami. Na przykład "1 4" oznacza krawędź między węzłem 1 i 4.

Problem polega na tym, wyjście powinno być tak:

[[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]] 

Ale zamiast tego, otrzymuję to:

[[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]] 

Tylko jeden numer jest inny i nie mogę zrozumieć, dlaczego tak się dzieje. Krawędź "3 1" nie jest obecna. Czy ktoś może wyjaśnić, gdzie jest problem?

+2

Dlaczego używacie znaleźć ... może po prostu użyć rozłamu i analizować jako int()? –

Odpowiedz

3

Matthias ma to; nie potrzebujesz edgeCount - 1, ponieważ funkcja range nie zawiera wartości końcowej w iteracji.

Istnieje kilka innych rzeczy, które można zrobić, aby oczyścić swój kod:

  • Operator with jest korzystna do otwierania plików, ponieważ zamyka je automatycznie Ci
  • Nie trzeba zadzwonić find i ręcznie wycinanie, split robi już to, co chcesz.
  • Można konwertować i przypisać bezpośrednio do pary liczb przy użyciu wyrażenia generatora i iterable rozpakowaniu
  • Można zadzwonić range tylko z wartością końcową, początek 0 jest niejawna.
  • Operator mnożenia jest przydatny do inicjalizacji list

Z wszystkich tych zmian:

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]] 
+0

Ale kiedy usuwam -1 z zakresu(), pojawia się ten błąd: Traceback (ostatnie ostatnie połączenie): Plik "X: \ Őkola \ IVT \ Python \ Graph01_test.py", wiersz 18, w gp_to = int (gp [gp_splitIndex + 1: -1]) ValueError: niepoprawny literał dla int() z base 10: '' –

+0

Po prostu użyj 'split' zamiast' find' i kroisz tak, jak pokazuję w moim przykładowym kodzie. W przeciwnym razie pomiń '-1' od końca - po prostu użyj' [gp_splitIndex + 1:] '- wprowadzenie' -1' oznacza, że ​​przeskakujesz ostatnią postać. – tzaman

5

Zmień for i in range(0, gp_edgeCount-1): do

for i in range(0, gp_edgeCount): 

Funkcja range() już robi "-1" operację. range(0,3) "==" [0,1,2]

Nie brakuje krawędzi "3 1", brakuje jej "2 0" i jest to ostatnia krawędź. Macierze zaczynają odliczanie o wartości 0.

2

Wystarczy, aby utrzymać swój kod i styl, oczywiście może to być o wiele bardziej czytelny:

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 

Dokładnie nie użyto ostatniej instancji ... 2 0 z Twojego pliku. Tak więc brakowało 1. Miłego dnia!

0

innych odpowiedzi są poprawne, inna wersja podobna do jednej z 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