为什么循环在仅一次迭代中会表现不同?

7

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

文件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”不存在。有人能解释一下问题出在哪里吗?


2
为什么要使用find...你不能只使用split和parse as int()吗? - Marco smdm
4个回答

5

for i in range(0, gp_edgeCount-1): 改为

for i in range(0, gp_edgeCount):
range()函数已经进行了“-1”操作。range(0,3) "==" [0,1,2] 缺失的不是“3 1”这条边,而是“2 0”这条边,这是最后一条边。矩阵从0开始计数。

3

Matthias已经解决了这个问题;因为range函数在迭代时不包括结束值,所以你不需要edgeCount - 1

还有其他一些可以优化你的代码的方法:

  • 使用with操作符打开文件更好,因为它会自动关闭文件。
  • 你不需要调用find并手动切片,split已经实现了你想要的功能。
  • 你可以使用生成器表达式和可迭代解包直接转换和赋值给一对数字。
  • 你可以仅使用一个结束值来调用range0的起始值是隐含的。
  • 乘法操作符对于初始化列表非常方便。

通过以上所有改变:

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

但是当我从range()中删除-1时,我会得到以下错误: Traceback (most recent call last): File "X:\Őkola\IVT\Python\Graph01_test.py", line 18, in <module> gp_to = int(gp[gp_splitIndex+1:-1]) ValueError: invalid literal for int() with base 10: '' - Adam Bajger
只需像我在示例代码中展示的那样使用 split 而不是 find 和切片。否则,从末尾省略 -1 -- 只需使用 [gp_splitIndex+1:] -- 在那里放置 -1 意味着你跳过了最后一个字符。 - tzaman

2

为了保持你的代码和样式,当然它可以更易读:

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

您的文件中最后一个实例未被使用,因此漏掉了1。祝您拥有愉快的一天!


1
其他回答是正确的,另一个类似于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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接