Python: Как мне записать список в файл, а затем вытащить его обратно в память (dict, представленный в виде строки, преобразованной в dict) позже? - PullRequest
28 голосов
/ 21 мая 2009

Более конкретное дублирование 875228 - Простое хранение данных в Python .

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

В настоящее время каждый раз, когда я думаю о новых функциях, мне приходится их писать, а затем заново генерировать диктат. Я ищу способ записать этот dict в файл, чтобы я мог загрузить его в память вместо пересчета всех его значений.

для упрощения вещей это выглядит примерно так: {((((«слово», «список»), (1,2), (1,3)), (...)): 0,0, ....}

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

Ответы [ 6 ]

60 голосов
/ 21 мая 2009

Почему бы не использовать Python Pickle ? В Python есть отличный модуль сериализации, называемый pickle, который очень прост в использовании.

import cPickle
cPickle.dump(obj, open('save.p', 'wb')) 
obj = cPickle.load(open('save.p', 'rb'))

У маринада есть два недостатка:

  • Он не защищен от ошибочного или вредоносные данные. Никогда распаковать данные, полученные от ненадежный или не прошедший проверку подлинности источник.
  • Формат не читается человеком.

Если вы используете Python 2.6, есть встроенный модуль с именем json . Это так же просто, как рассол:

import json
encoded = json.dumps(obj)
obj = json.loads(encoded)

Формат Json удобен для чтения и очень похож на строковое представление словаря в python. И не имеет никаких проблем с безопасностью, как рассол. Но может быть медленнее, чем cPickle.

12 голосов
/ 21 мая 2009

Я бы использовал shelve, json, yaml или что-то еще, как подсказывают другие ответы.

shelve особенно круто, потому что вы можете иметь dict на диске и по-прежнему использовать его. Значения будут загружаться по требованию.

Но если вы действительно хотите разобрать текст dict, и он содержит только str ings, int s и tuple s, как вы показали, вы можете использовать ast.literal_eval чтобы разобрать его. Это намного безопаснее, поскольку вы не можете использовать полные выражения с ним - он работает только с str, числами, tuple с, list с, dict с, bool eans и None

>>> import ast
>>> print ast.literal_eval("{12: 'mydict', 14: (1, 2, 3)}")
{12: 'mydict', 14: (1, 2, 3)}
4 голосов
/ 21 мая 2009

Я бы посоветовал вам использовать YAML для вашего формата файла, чтобы вы могли повозиться с ним на диске

How does it look:
  - It is indent based
  - It can represent dictionaries and lists
  - It is easy for humans to understand
An example: This block of code is an example of YAML (a dict holding a list and a string)
Full syntax: http://www.yaml.org/refcard.html

Чтобы получить его в python, просто easy_install pyyaml. Смотри http://pyyaml.org/

Он поставляется с простыми функциями сохранения / загрузки файлов, которые я не могу вспомнить прямо сейчас.

0 голосов
/ 05 ноября 2012

Вот несколько вариантов в зависимости от ваших требований:

  • numpy хранит ваши простые данные в компактной форме и хорошо выполняет групповые / массовые операции

  • shelve походит на большой диктовку, подкрепленную файлом

  • какой-то сторонний модуль хранения, например stash, хранит произвольные простые данные

  • правильная база данных, например, mongodb для волосатых данных или простых данных mysql или sqlite и более быстрый поиск

0 голосов
/ 03 октября 2009

В этом решении на SourceForge используются только стандартные модули Python:

модуль y_serial.py :: хранилище объектов Python с SQLite

"Сериализация + постоянство :: в несколько строк кода сжимают и аннотируют объекты Python в SQLite, а затем извлекают их в хронологическом порядке по ключевым словам без какого-либо SQL. Наиболее полезный" стандартный "модуль для базы данных для хранения данных без схемы . "

http://yserial.sourceforge.net

Бонус сжатия, вероятно, уменьшит ваш словарь на 6 ГБ до 1 ГБ. Если вы не хотите хранить серию словарей, модуль также содержит решение file.gz, которое может быть более подходящим с учетом размера вашего словаря.

0 голосов
/ 21 мая 2009

Запишите его в сериализованном формате, таком как pickle (стандартный модуль библиотеки Python для сериализации) или, возможно, с помощью JSON (это представление, которое может быть обработано для создания представления памяти снова).

...