Файл Произвольного Доступа Python

есть ли тип файла Python для доступа к случайным строкам без обхода всего файла? Мне нужно искать в большом файле, чтение всего этого в память было бы невозможно.

любые типы или методы будут оценены.

7 ответов


это похоже на что-то вроде mmap была разработана для. А mmap объект создает строковый интерфейс для файла:

>>> f = open("bonnie.txt", "wb")
>>> f.write("My Bonnie lies over the ocean.")
>>> f.close()
>>> f.open("bonnie.txt", "r+b")
>>> mm = mmap(f.fileno(), 0)
>>> print mm[3:9]
Bonnie

если вам интересно,mmap объекты также могут быть назначены:

>>> print mm[24:]
ocean.
>>> mm[24:] = "sea.  "
>>> print mm[:]
My Bonnie lies over the sea.  

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

Если kinda-sorta-random достаточно, вы можете искать случайное место в файле, а затем читать вперед, пока не нажмете Терминатор линии. Но это бесполезно, если вы хотите найти (скажем) номер строки 1234 и будете выбирать линии неравномерно, если вы на самом деле хотите случайно выбранную строку.


можно использовать linecache:

import linecache
print linecache.getline(your_file.txt, randomLineNumber) # Note: first line is 1, not 0

файловые объекты имеют метод seek, который может принимать значение определенного байта в этом файле. Для прохождения через большие файлы, повторите его и проверьте значение в каждой строке. Итерация объекта file не загружает все содержимое файла в память.


Да, вы можете легко получить случайную строку. Просто найдите случайную позицию в файле, затем ищите к началу, пока не нажмете \n или начало файла, затем прочитайте строку.

код:

import sys,random
with open(sys.argv[1],"r") as f:
    f.seek(0,2)                 # seek to end of file
    bytes = f.tell()
    f.seek(int(bytes*random.random()))

    # Now seek forward until beginning of file or we get a \n
    while True:
        f.seek(-2,1)
        ch = f.read(1)
        if ch=='\n': break
        if f.tell()==1: break

    # Now get a line
    print f.readline()

объект File поддерживает seek, но убедитесь, что вы открываете их как двоичные, т. е. "rb".

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


имеет фиксированную длину записи? Если да, то да, вы можете реализовать алгоритм бинарного поиска с помощью поиска.

в противном случае загрузите файл в базу данных SQLlite. Запрос.