Python: создать словарь из текста/файла в формате словаря

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

{'олень': [1], 'сермерсхейм': [3], 'сонджи': [2], 'шеринг': [2]}

Это точно так, за исключением того, что он содержит 125 000 записей. Я могу читать текстовый файл с помощью read(), но он создает переменную буквального текста файла, даже когда я инициализирую переменную с помощью

словарь = {}


person Jared    schedule 16.02.2012    source источник
comment
@JBernardo +1, если у вас есть Python 2.6 или новее, это то, что вам нужно. Модуль ast появился в версии 2.5, но не имел вспомогательных функций (таких как literal_eval). Они появились в 2.6.   -  person Steven T. Snyder    schedule 16.02.2012
comment
@JBernardo, лучший ответ   -  person dzhioev    schedule 24.07.2013


Ответы (6)


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

dicts_from_file = []
with open('myfile.txt','r') as inf:
    for line in inf:
        dicts_from_file.append(eval(line))    
# dicts_from_file now contains the dictionaries created from the text file

В качестве альтернативы, если файл представляет собой один большой словарь (даже в несколько строк), вы можете сделать это:

with open('myfile.txt','r') as inf:
    dict_from_file = eval(inf.read())

Это, наверное, самый простой способ сделать это, но не самый безопасный. Как уже упоминалось в их ответах, eval имеет некоторые неотъемлемые риски безопасности. Альтернативой, как упоминал Дж. Бернардо, является использование ast.literal_eval, что намного безопаснее, чем eval, поскольку он будет оценивать только строки, содержащие литералы. Вы можете просто заменить все вызовы eval в приведенных выше примерах на ast.literal_eval после импорта модуля ast.

Если вы используете Python 2.4, у вас не будет модуля ast и у вас не будет with. Код будет выглядеть примерно так:

inf = open('myfile.txt','r')
dict_from_file = eval(inf.read())
inf.close()

Не забудьте позвонить inf.close(). Прелесть операторов with в том, что они делают это за вас, даже если блок кода в операторе with вызывает исключение.

person Steven T. Snyder    schedule 16.02.2012
comment
Что, если это просто стена текста? Это буквально сплошная строка, начинающаяся с { и заканчивающаяся на }. - person Jared; 16.02.2012
comment
Он будет работать, если есть только одна строка, но не будет работать, если словарь распределен более чем по одной строке. Я добавил дополнительный код для этого случая. - person Steven T. Snyder; 16.02.2012
comment
Я получаю «недопустимый синтаксис» с › with open('myfile.txt','r') as inf: line. - person Jared; 16.02.2012
comment
Вы используете Python 2.5 или новее? - person Steven T. Snyder; 16.02.2012
comment
@Jared Я отредактировал свой ответ, включив в него некоторые примечания об использовании версии Python старше 2.5, которая, похоже, у вас есть. По сути, у вас не будет операторов with (не слишком важно) и модуля ast. - person Steven T. Snyder; 16.02.2012
comment
Да, вы выиграли Pickle @Series8217. У меня 2.4 на этом компьютере и 2.5 на другом (основном), так что я не знал, что с ним не будет работать! - person Jared; 16.02.2012
comment
К вашему сведению: похоже, что метод теперь ast.literal_eval, а не ast.literaleval - person Taylor Edmiston; 30.07.2013
comment
@ted Спасибо, я исправил - person Steven T. Snyder; 30.07.2013

Используйте функцию eval.

Например,

dict = eval(open("yourfile.txt").read())
person Community    schedule 16.02.2012
comment
+1 eval определенно самое простое. Комментарий, сделанный @JBernardo о ast.literal_eval, безопаснее, поскольку он допускает только строки, числа, кортежи, списки, словари, логические значения и None. Просто что-то рассмотреть. - person istruble; 16.02.2012

Использование eval может быть опасным. Если json не работает, я бы рекомендовал использовать yaml, который, кажется, отлично работает с вашим примером ввода :

>>> import yaml
>>> yaml.load("{'fawn': [1], 'sermersheim': [3], 'sonji': [2], 'scheuring': [2]}")
{'fawn': [1], 'scheuring': [2], 'sermersheim': [3], 'sonji': [2]}
person jcollado    schedule 16.02.2012
comment
Ах, я бы хотел использовать это, но у меня нет модуля, а система, в которой выполняется код, не имеет доступа в Интернет. Спасибо, в любом случае! - person Jared; 16.02.2012
comment
В любом случае, вы можете рассмотреть возможность установки из исходного кода. Согласно документации, это должно быть так же просто, как: python setup.py install. - person jcollado; 16.02.2012

Это не готовое к производству решение и может не работать с файлом вашего размера, но если вам нужен простой способ и вы можете добавить файл к

my_dict = {'fawn': [1], 'sermersheim': [3], 'sonji': [2], 'scheuring': [2]}

затем вы можете переименовать его в файл python и просто импортировать

from my_file import my_dict 
person user1587520    schedule 19.02.2017

Однако я крайне не рекомендую использовать eval. Это может привести к проблемам с безопасностью, если у вас нет полного контроля над входным файлом. Просто импортируйте словарь и сохраните его с помощью модуля json или pickle.

person nopper    schedule 16.02.2012
comment
Я согласен с тем, что eval представляет собой огромную угрозу безопасности, если используется на регулярной основе или в производственном коде. Я интерпретировал исходный вопрос как работу с изолированным фрагментом кода, полученным из надежного источника и уже находящимся в текстовом файле. В такой ситуации больше ничего не поделаешь. - person ; 16.02.2012
comment
Это статический файл из надежного источника, да! - person Jared; 16.02.2012
comment
И мне не повезло с файлами рассола. У меня есть такая же информация в файле .pickle, но я не могу загрузить его обратно. Этот код запускается в системе с ограниченным доступом без доступа в Интернет. - person Jared; 16.02.2012
comment
@Jared Возможно, вам следует опубликовать вопрос о ваших проблемах с pickle, так как это кажется настоящей проблемой. - person jcollado; 16.02.2012

Для меня это похоже на json. Если это так, используйте модуль json.

Это похоже на yaml для меня. Если да, используйте модуль pyyaml. (Как предложил @jcollado).

Вы не можете использовать модуль json, потому что он строго относится к вводу.

person Marcin    schedule 16.02.2012
comment
Это не JSON: вместо двойных кавычек используются одинарные кавычки. - person Ned Batchelder; 16.02.2012
comment
@NedBatchelder: Да. Я не осознавал, что модуль json был строг в отношении своих входных данных. - person Marcin; 16.02.2012