У меня есть этот код:

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

Файл graph.txt содержит это:

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

Первые два числа говорят мне, что GRAPH имеет 5 узлов и 10 ребер. Следующие пары чисел демонстрируют ребра между узлами. Например, «1 4» означает ребро между узлами 1 и 4.

Проблема в том, что вывод должен быть таким:

[[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, 1, 0, 1, 0], [0, 0, 1, 0, 1], [0, 0, 0, 1, 0], [0, 1, 0, 0, 1], [1, 0, 1, 0, 0]]

Только одно число отличается, и я не могу понять, почему это происходит. Края "3 1" нет. Может кто-нибудь объяснить, в чем проблема?

7
Adam Bajger 8 Дек 2016 в 14:00

4 ответа

Лучший ответ

Матиас имеет это; вам не нужен edgeCount - 1, так как функция range не включает конечное значение в итерации.

Есть несколько других вещей, которые вы можете сделать, чтобы очистить свой код:

  • Оператор with предпочтителен для открытия файлов, поскольку он автоматически закрывает их для вас.
  • Вам не нужно вызывать find и вручную нарезать, split уже делает то, что вы хотите.
  • Вы можете конвертировать и присваивать напрямую паре чисел, используя выражение генератора и повторяемую распаковку
  • Вы можете вызвать range только с конечным значением, начало 0 неявно.
  • Оператор умножения удобен для инициализации списков.

Со всеми этими изменениями:

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
tzaman 8 Дек 2016 в 14:17

Изменить for i in range(0, gp_edgeCount-1): на

for i in range(0, gp_edgeCount):

Функция range() уже выполняет операцию "-1". { { Х1 }}

И это не край "3 1", который пропущен, это край "2 0", который пропущен, и это последний край. Матрицы начинают отсчитывать с 0.

5
Matthias 8 Дек 2016 в 14:03

Просто чтобы сохранить ваш код и стиль, конечно, это может быть гораздо более читабельным:

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

Точно последний экземпляр не используется .. 2 0 из вашего файла. Таким образом пропустили 1. Хорошего дня!

2
Marco smdm 8 Дек 2016 в 14:24

Другие ответы верны, другая версия похожа на версию Цамана:

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
1
wibr 8 Дек 2016 в 14:34