Элегантный способ хранения словаря на Python?

В настоящее время дорого анализируется файл, который генерирует словарь с ~ 400 ключами, парами значений, которые редко обновляются. Ранее была функция, которая разбирала файл, записывала его в текстовый файл в синтаксисе словаря (т.е. dict = {'Adam': 'Room 430', 'Bob': 'Room 404'}) и т.д., И копировала и вставляла его в другую функцию, единственной целью которой было вернуть этот разборный словарь.

Следовательно, в каждом файле, где я бы использовал этот словарь, я бы импортировал эту функцию и назначил ее переменной, которая теперь является этим словарем. Хотите узнать, есть ли более элегантный способ сделать это, что не связано с явным копированием и вводом кода? Использование типа базы данных кажется ненужным, и текстовый файл дал мне понять, правильно ли был проведен синтаксический анализ, прежде чем добавлять его в функцию. Но я открыт для предложений.

Ответы

Ответ 1

Почему бы не выгрузить его в файл JSON, а затем загрузить его там, где он вам нужен?

import json

with open('my_dict.json', 'w') as f:
    json.dump(my_dict, f)

# elsewhere...

with open('my_dict.json') as f:
    my_dict = json.load(f)

Загрузка из JSON довольно эффективна.

Другой вариант - использовать pickle, но, в отличие от JSON, файлы, которые он генерирует, не читаются человеком, поэтому вы теряете на визуальную проверку, которую вам понравился из старого метода.

Ответ 2

Зачем возиться со всеми этими методами сериализации? Он уже записан в файл как питоновский дикт (хотя и с неудачным именем "dict" ). Измените свою программу, чтобы записать данные с лучшим именем переменной - возможно, "данные" или "каталог", и сохранить файл в виде файла Python, скажем, data.py. Затем вы можете просто импортировать данные непосредственно во время выполнения без каких-либо неуклюжей копии/вставки или JSON/shelve/etc. синтаксический анализ:

from data import catalog

Ответ 3

JSON, вероятно, является правильным способом во многих случаях; но может быть и альтернатива. Похоже, что ваши ключи и ваши значения всегда являются строками, верно? Вы можете использовать dbm/anydbm. Это "базы данных", но они действуют почти как словари. Они отлично подходят для дешевого сохранения данных.

>>> import anydbm
>>> dict_of_strings = anydbm.open('data', 'c')
>>> dict_of_strings['foo'] = 'bar'
>>> dict_of_strings.close()
>>> dict_of_strings = anydbm.open('data')
>>> dict_of_strings['foo']
'bar'

Ответ 4

Если все клавиши являются строками, вы можете использовать shelve модуль

A полка - это постоянный, словарь-подобный объект. Разница с Базы данных "dbm" состоят в том, что значения (а не ключи!) на полке могут быть по существу произвольные объекты Python - все, что модуль рассола может справиться. Это включает в себя большинство экземпляров классов, рекурсивных типов данных, и объекты, содержащие множество общих под-объектов. Ключи обычные строки.

json будет хорошим выбором, если вам нужно использовать данные с других языков

Ответ 5

Если эффективность хранения важна, используйте Pickle или CPickle (для увеличения производительности исполнения). Как отметил Амбер, вы также можете сбросить/загрузить через Json. Он будет читабельным для человека, но требует больше диска.

Ответ 6

Я предлагаю вам использовать модуль shelve, так как ваша структура данных является сопоставлением. Это был мой ответ на аналогичный вопрос под названием Если я хочу создать пользовательскую базу данных, как я могу? Там также немного пример кода в другом ответе моего содействия его использованию для вопроса Как получить базу данных объекта?

ActiveState имеет высоко оцененный PersistentDict, который поддерживает форматы выходных файлов csv, json и pickle. Это довольно быстро, так как все три из этих форматов реализованы в C (хотя сам рецепт - чистый Python), поэтому факт, что он читает весь файл в памяти при его открытии, может быть приемлемым.

Ответ 7

в направлении JSON есть также нечто вроде simpleJSON. Мой первый раз, используя json в python, библиотека json did not работает для меня/я не мог понять это. simpleJSON был... проще в использовании

Ответ 8

Сериализация JSON (или YAML или что-то другое), вероятно, лучше, но если вы уже пишете словарь в текстовый файл в синтаксисе python, в комплекте с привязкой имен переменных, вы можете просто написать это в .py файл вместо. Тогда этот файл python будет импортироваться и использоваться как есть. Нет необходимости в "функции, которая возвращает словарь", поскольку вы можете напрямую использовать ее как глобальную в этом файле. например.

# generated.py
please_dont_use_dict_as_a_variable_name = {'Adam': 'Room 430', 'Bob': 'Room 404'}

а не:

# manually_copied.py
def get_dict():
    return {'Adam': 'Room 430', 'Bob': 'Room 404'}

Единственное отличие состоит в том, что manually_copied.get_dict дает вам новую копию словаря каждый раз, тогда как generated.please_dont_use_dict_as_a_variable_name [1] - это один общий объект. Это может иметь значение, если вы изменяете словарь в своей программе после его получения, но всегда можете использовать copy.copy или copy.deepcopy для создания новой копии, если вам нужно изменить ее независимо от других.


[1] dict, list, str, int, map и т.д. обычно рассматриваются как неправильные имена переменных. Причина в том, что они уже определены как встроенные и используются очень часто. Поэтому, если вы дадите что-то подобное, по крайней мере, это вызовет когнитивно-диссонанс для людей, читающих ваш код (включая вас после того, как вы ушли на какое-то время), поскольку им нужно помнить, что "dict не означает, что это обычно здесь". Также вполне вероятно, что в какой-то момент вы получите сообщение об ошибке, указывающее на то, что объекты dict не вызываются (или что-то еще), потому что какой-то фрагмент кода пытается использовать тип dict, но получает объект словаря, который вы привязали к имени dict.