Уведомления

Группа в Telegram: @pythonsu

#1 Июнь 5, 2015 18:24:22

Alef
Зарегистрирован: 2015-06-05
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

Переход к строке в файле по ее номеру

Здравствуйте!

Есть ли в питоне возможность считать только одну конкретную строку из файла по ее номеру, не считывая всех предыдущих?

Полдня ищу в интернете ответ на этот вопрос, но найти ничего не получается. Все пытаются читать файл построчно до нахождения искомой строки. Но мне надо именно и только одну строку прочитать, а все остальные - нет!

Дело в том, что я пытаюсь обрабатывать текстовый файл размером 10Гб и операцию считывания строки мне надо повторить что-то где-то пару миллионов раз, если навскидку (если быть оптимистами, может оказаться, что 7-8 сотен тысяч)…. Если читать с начала файла и до нужной строки, это не долго и даже не ДОЛГО, а попросту ДОЛГО!

Есть ли какая-то возможность сразу перейти к нужной строке? Или стоит просто другой язык программирования использовать? ??

(строки разного размера все, и я знаю именно и только номер нужной, а не ее байтовую позицию в файле)

Отредактировано Alef (Июнь 5, 2015 18:34:15)

Офлайн

#2 Июнь 5, 2015 18:50:36

terabayt
От: Киев
Зарегистрирован: 2011-11-26
Сообщения: 1099
Репутация: +  103  -
Профиль   Отправить e-mail  

Переход к строке в файле по ее номеру

import linecache
print linecache.getline('Test.txt', 4)
где Test.txt это путь к файлу, а 4 это номер строки



————————————————
-*- Simple is better than complex -*-

Офлайн

#3 Июнь 5, 2015 19:08:01

Alef
Зарегистрирован: 2015-06-05
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

Переход к строке в файле по ее номеру

Пишет:

  File "C:\Python34\lib\codecs.py", line 319, in decode
    (result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc4 in position 516: invalid continuation byte

Офлайн

#4 Июнь 5, 2015 19:42:19

terabayt
От: Киев
Зарегистрирован: 2011-11-26
Сообщения: 1099
Репутация: +  103  -
Профиль   Отправить e-mail  

Переход к строке в файле по ее номеру

виндовс…
это проблема с выводом
сделайте без принта, прост в переменную

import linecache
a = linecache.getline('Test.txt', 4)
ошибки не должно быть

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

еще можно так сделать
with open('Test.txt') as f:
    for i in xrange(2000000):
        f.readline()
    print(f.readline())
где 2000000 это количество строк котрые нужно пропустить
так даже быстрее



————————————————
-*- Simple is better than complex -*-

Офлайн

#5 Июнь 5, 2015 19:47:40

Alef
Зарегистрирован: 2015-06-05
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

Переход к строке в файле по ее номеру

Спасибо за помощь!

К сожалению, даже пропуск строк для меня слишком медленно: он может занимать до минуты, учитывая, что повторять это надо несколько сотен тысяч раз…. я даже сомневаюсь, что все это, запущенное на выходные, к понедельнику отработает

Изначально я такое использую:

def read_f(k,f):
    i = 0
    while i < k:
        f.readline()
        i += 1

Замеряла время исполнения для одной строки - даже если все другие процессы на компе убить, все равно для строк из конца файла больше минуты листает

Ошибку выдает именно при записи в переменную (я так изначально и переделала)
Странно, что если создать файл в блокноте и с ним это все проделать - ошибки нет. А вот с этим 10-гиговым - вот такое…

Про кодировку как раз сейчас гуглю) Пока ничего не находится, точнее, находится много, но не про то…

Но вы меня столкнули с мертвой точки, благодарю!

Отредактировано Alef (Июнь 5, 2015 19:52:40)

Офлайн

#6 Июнь 5, 2015 19:51:56

terabayt
От: Киев
Зарегистрирован: 2011-11-26
Сообщения: 1099
Репутация: +  103  -
Профиль   Отправить e-mail  

Переход к строке в файле по ее номеру

Alef
Странно, что если создать файл в блокноте и с ним это все проделать - ошибки нет. А вот с этим 10-гиговым - вот такое…
измените кодировку
можно через sublime

Alef
К сожалению, даже пропуск строк для меня слишком медленно: он может занимать до минуты, учитывая, что повторять это надо несколько сотен тысяч раз
это проблема
нужно что-то получше придумать
а для этого нужно знать что вы хотите
напишите условие, можно на почту

еще можно через enumerate он создает генератор. может так будет и быстрее
with open('Test.txt') as f:
    for i, j in enumerate(f):
        if i == 200000:
            print(j)
            break



————————————————
-*- Simple is better than complex -*-

Отредактировано terabayt (Июнь 5, 2015 20:14:30)

Офлайн

#7 Июнь 5, 2015 21:00:03

Alef
Зарегистрирован: 2015-06-05
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

Переход к строке в файле по ее номеру

Спасибо!!!
Я обязательно это попробую, только уже, пожалуй, на выходных) Что-то ничего не соображаю. Пыталась файл в utf-8 конвертнуть средствами самого питона, получился такой ужас, не передать… похоже, стоит перерыв сделать

Да, я написала в почту, на всякий случай… )

Офлайн

#8 Июнь 6, 2015 01:55:26

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10031
Репутация: +  857  -
Профиль   Отправить e-mail  

Переход к строке в файле по ее номеру

Alef
Есть ли какая-то возможность сразу перейти к нужной строке?
Строка определяется признаком конца - одним или двумя символами. То есть строка - это просто последовательность символов, включающая признак конца. Символ может быть представлен разным количеством байт, которое зависит от символьной кодировки. (Например символ \n в кодировке utf-32 будет занимать 4 байта, а в utf-8 - 1 байт.)

Файл можно читать последовательно, а можно читать произвольно.
При последовательном чтении для перехода ко второму символу нужно прочитать первый, а для перехода к третьему нужно прочитать второй.
При произвольном доступе можно сразу перейти к байтовой позиции.

Позиция символа и позиция байта могут не совпадать из-за символьной кодировки, так как символ может представляться разным количеством байт. Поэтому при чтении символов требуется сначала дойти до нужного символа, а потом сохранить его байтовую позицию (специальная функция сама понимает, какой байт сохранить). А восстановление выполняется через другую функцию, которая принимает эту сохранённую ранее байтовую позицию символа.
Это не строго, поэтому нигде не говорится, что сохраняется именно байтовая позиция символа. Говорят, что сохраняется какое-то число.

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



Офлайн

#9 Июнь 6, 2015 10:42:23

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 4138
Репутация: +  253  -
Профиль   Отправить e-mail  

Переход к строке в файле по ее номеру

Alef
Или стоит просто другой язык программирования использовать? ??
Немного дополню предыдущий ответ. Новый язык искать не стоит, потому что не существует никакого языка программирования который это позволит сделать. Файл операционной системы не содержит интерфейса для поиска строк.

Лепить индекс самостоятельно тоже смысла нет, поскольку задача много раз уже решалась. Запихивайте файл в базу данных и получите доступ по строкам.
http://stromberg.dnsalias.org/~strombrg/python-tree-and-heap-comparison/implementation.html

В любом случае один раз файл все равно надо прочитать полностью.

Пример загрузки файла:
Команда:
sqlite3.exe ex1.db

create table file_rows(a);
.mode csv
.separator "@"
.import you_file_name file_rows

предполагается что ваш файл называется you_file_name и строки не содержат @



Офлайн

#10 Июнь 9, 2015 17:08:01

Alef
Зарегистрирован: 2015-06-05
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

Переход к строке в файле по ее номеру

Огромное всем спасибо!
Удалось победить эти файлы, выписав отдельно байтовые позиции нужных строк (это ведь и называется индексами, или я что-то путаю?). Теперь оно практически летает

С базами данных тоже попробую, чисто из интереса, но задача разрешилась) Благодарю!

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version