Python: Как мне записать список в файл и затем извлечь его обратно в память (dict, представленный в виде строки, преобразованной в dict) позже?

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

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

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

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

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

7 ответов

Почему бы не использовать 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.

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

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

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

>>> import ast
>>> print ast.literal_eval("{12: 'mydict', 14: (1, 2, 3)}")
{12: 'mydict', 14: (1, 2, 3)}

Я бы посоветовал вам использовать 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/

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

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

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

  • shelve это как большой диктат, заархивированный файлом

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

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

Это решение в SourceForge использует только стандартные модули Python:

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

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

http://yserial.sourceforge.net/

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

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

Для символов Unicode используйте:

      data = [{'key': 1, 'text': 'some text'}]
f = open(path_to_file, 'w', encoding='utf8')
json.dump(data, f, ensure_ascii=False)
f.close()

f = open(path_to_file, encoding="utf8")
data = json.load(f)

print(data)

[{'ключ': 1, 'текст': 'некоторый текст'}]

Другие вопросы по тегам