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, 'текст': 'некоторый текст'}]