Как записать списки «один за другим» в двоичный файл на python?

1

У меня есть фрагмент кода, который генерирует довольно большие списки на каждой итерации. Чтобы сохранить память, я хочу записать каждый список в двоичный файл на каждой итерации после создания списка. Я пробовал это с текстовыми файлами (даже установив параметр в "wb" в linux). "wb", похоже, не имеет никакого эффекта для записи файла в двоичном или текстовом формате. Более того, письменный файл огромен, и я не хочу этого. Я уверен, что если я смогу записать эти списки в двоичном формате, этот файл будет намного меньше. спасибо

  • 1
    Какой тип элементов списка? Является ли использование NumPy вариант?
  • 3
    Не существует такого понятия, как «двоичный формат». Существуют форматы, которые не похожи на текст в любой кодировке (соответственно, не должны). Тем не менее, существует множество таких форматов и бесконечное количество возможных. Какой двоичный формат вы хотите?
Показать ещё 2 комментария
Теги:
file
list
binary

3 ответа

4
Лучший ответ

Поскольку вы упомянули о необходимости сжимаемости, я бы предложил использовать pickle с помощью gzip для сжатия вашего вывода. Вы можете писать и читать свои списки по одному, вот пример того, как:

import gzip, pickle

output = gzip.open('pickled.gz', 'wb', compresslevel=9)

for x in range(10):
     output.write(pickle.dumps(range(10)) + '\n\n')
output.close()

И затем используйте генератор для отображения списков по одному за раз:

def unpickler(input):
    partial = []
    for line in input:
        partial.append(line)
        if line == '\n':
            obj = ''.join(partial)
            partial = []
            yield pickle.loads(obj)

input = gzip.open('pickled.gz', 'rb')
for l in unpickler(input):
    print l

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  • 0
    @zeekey: спасибо за ваш код, но проблема в том, что, как я уже говорил, этот список списков будет очень большим, чтобы сначала поместиться в память, а затем записать его в файл. Мне нужно написать список за списком в файл, чтобы не исчерпать память.
  • 0
    Вы можете сбрасывать свои засоленные объекты по одному, используя '\ n \ n' (или что-то подобное) для разделения записей.
Показать ещё 1 комментарий
1

Единственное, что изменил флаг 'b', - это то, как выполняются переводы строк для поддержки Windows.

import pickle
help(pickle.load)
help(pickle.dump)

# seems fairly efficient, taking 200bytes to store [1,2,...,100],
# 2.7kb to store [1,2,...,1000],
# and 29kb to store [1,2,...,10000]:
>>> len(pickle.dumps(list(range(100))))
208
>>> len(pickle.dumps(list(range(1000))))
2752
>>> len(pickle.dumps(list(range(10000))))
29770

#create and store
data = {}
data['myList'] = [i for i in range(100)]
with open('myfile.pickle', 'wb') as f:
    pickle.dump(data, f)

# retrieve
with open('myfile.pickle', 'wb') as f:
    data2 = pickle.load(f)
print(data2)

Обратите внимание, что использовать pickle для любых пользовательских данных небезопасно. Вам нужно будет открыть файл, который вы пишете, в двоичном режиме.

1

Вы можете использовать cPickle для сериализации ваших списков и выгрузки результата в файл.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню