Как прочитать определенное количество поплавков из файла в Python? - PullRequest
1 голос
/ 21 апреля 2010

Я читаю текстовый файл из Интернета. Файл начинается с нескольких строк заголовка, содержащих количество точек данных, за которыми следуют фактические вершины (по 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 ]

3 голосов
/ 21 апреля 2010

Я не совсем уверен, какова ваша цель из вашего объяснения.

Для справки, вот код, который делает в основном то же самое, что и ваш, похоже, пытается использовать некоторые методы, которые я бы использовал по сравнению с теми, которые вы выбрали. Обычно это признак того, что вы делаете что-то не так, если используете циклы 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))

Если вы более откровенно говорите о новой вещи, которую вы хотите сделать, возможно, кто-то может дать лучший ответ для вашей конечной цели.

0 голосов
/ 21 апреля 2010

Вот очистка вашего кода без лишних хлопот, которая должна значительно ускорить зацикливание содержимого.

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 () и сколько распаковывает строки?

...