如何在Python中从文件读取特定数量的浮点数?

1 投票
2 回答
2189 浏览
提问于 2025-04-15 21:51

我正在从网上读取一个文本文件。这个文件的开头有一些标题行,里面包含了数据点的数量,接下来是实际的顶点(每个顶点有3个坐标)。文件的格式大致是这样的:

# comment
HEADER TEXT
POINTS 6 float
1.1 2.2 3.3 4.4 5.5 6.6 7.7 8.8 9.9
1.1 2.2 3.3 4.4 5.5 6.6 7.7 8.8 9.9
POLYGONS

POINTS开头的那一行包含了顶点的数量(在这个例子中,每行有3个顶点,但这个数量可能会变化)

这是我现在读取文件的方式:

ur=urlopen("http://.../file.dat")

j=0
contents = []
while 1:
    line = ur.readline()
    if not line:
        break
    else:
        line=line.lower()       

    if 'points' in line :
        myline=line.strip()
        word=myline.split()
        node_number=int(word[1])
        node_type=word[2]

        while 'polygons'  not in line :
            line = ur.readline()
            line=line.lower() 
            myline=line.split()

            i=0
            while(i<len(myline)):                    
                contents[j]=float(myline[i])
                i=i+1
                j=j+1

我想知道怎么能一次性读取指定数量的浮点数,而不是一行一行地读取字符串再转换成浮点数?

我希望能直接读取文件中的指定数量的元素,而不是用ur.readline()这种方式

欢迎任何建议……

2 个回答

0

这里有个简单的方法,可以让你的代码在处理内容时运行得更快。

ur=urlopen("http://.../file.dat")
contents = []
node_number = 0
node_type = None
while 1:
    line = ur.readline()
    if not line:
        break
    line = line.lower()       
    if 'points' in line :
        word = line.split()
        node_number = int(word[1])
        node_type = word[2]
        while 1:
            pieces = ur.readline().split()
            if not pieces: continue # or break or issue error message
            if pieces[0].lower() == 'polygons': break
            contents.extend(map(float, pieces))
assert len(contents) == node_number * 3

如果把这些代码放到一个函数里,然后调用这个函数,它的运行速度会更快(因为这样你会使用局部变量,而不是全局变量)。

请注意,最重要的改动是在脚本的末尾附近。

不过:先停下来想一想:ur.readline()花了多少时间,解包这些行又花了多少时间?

3

我不太明白你解释的目标是什么。

顺便说一下,这里有段代码,它基本上和你想做的事情差不多,但我用了一些我认为更好的方法。一般来说,如果你在用while循环和索引,那可能说明你在做的事情有点问题。而且你的代码之所以不工作,是因为 contents[j] = ... 会导致一个 IndexError 错误。

lines = (line.strip().lower() for line in your_web_page)

points_line = next(line for line in lines if 'points' in line)
_, node_number, node_type = points_line.split()
node_number = int(node_number)

def get_contents(lines):
    for line in lines:
        if 'polygons' in line:
            break

        for number in line.split():
            yield float(number)

contents = list(get_contents(lines))

如果你能更明确地说明你想做的新事情,也许会有人能给你提供一个更好的答案,帮助你实现最终的目标。

撰写回答