2014-11-12 3 views
1

Можно ли перебирать список с помощью файла mmap? Дело в том, что список слишком велик (более 3 000 000 предметов). Мне нужно иметь быстрый доступ к этому списку при запуске программы, поэтому я не могу загрузить его в память после запуска программы, потому что это занимает несколько секунд.Перечислить через список с помощью mmap - Python

with open('list','rb') as f: 
    mmapList = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) # As far as I'm concerned, now I have the list mapped in a virtual memory. 

Теперь, я хочу перебрать этот список.

for a in mmapList не работает.

EDIT: Единственный способ, которым я знаю, - сохранить элементы списка в виде строк в txt-файле, а затем использовать readline, но мне любопытно, есть ли лучший и быстрый способ.

+0

Как был список сохранен в этот файл? – pbkhrv

+0

@pbkhrv Сохраняется с помощью cPickle, но я могу его изменить. –

+0

Объект mmap выполняет строку (https://docs.python.org/2/library/mmap.html), поэтому использование cPickle для десериализации вашего списка не является вариантом, не загружая сначала все в память. Тем не менее, можно написать простой генератор, так что «для a в mmapList» все равно будет работать, прогрессивно проходя через mmap с помощью readline(). Это поможет решить вашу проблему? – pbkhrv

ответ

0

Вам не нужно использовать mmap для повторения списка cPickled. Все, что вам нужно сделать, это не разборки всего списка, разборки и сброса каждого элемента, а затем их чтение по одному из файла (для этого можно использовать генератор).

Код:

import pickle 

def unpickle_iter(f): 
    while True: 
    try: 
     obj = pickle.load(f) 
    except EOFError: 
     break 
    yield obj 

def save_list(list, path): 
    with open(path, 'w') as f: 
    for i in list: 
     pickle.dump(i, f) 

def load_list(path): 
    with open(path, 'r') as f: 
    # here is your nice "for a in mmaplist" equivalent: 
    for obj in unpickle_iter(f): 
     print 'Loaded object:', obj 

save_list([1,2,'hello world!', dict()], 'test-pickle.dat') 
load_list('test-pickle.dat') 

Выход:

Loaded object: 1 
Loaded object: 2 
Loaded object: hello world! 
Loaded object: {} 
+0

Благодарим вас за советы. Я пробовал этот код, и он работает. Но я вынужден вернуться к решению для сохранения текста, потому что это занимает слишком много времени. Сохраняемое текстом решение mmap занимает 1,9 секунды в моем случае, и это решение занимает 7,8. –

+0

Интересно, звучит как unpickling, добавляет немного накладных расходов. Если производительность является проблемой, вот интересное обсуждение различных методов сериализации: http://stackoverflow.com/questions/9662757/python-performance-comparison-of-using-pickle-or-marshal-and-using-re – pbkhrv

Смежные вопросы