Python не читает выбранную строку из текстового файла, как в формате словаря.

У меня есть текстовый входной файл с различными входными данными, как показано ниже, в формате словаря и списка соответственно. Часть текстового файла приведена ниже:

#Drive-Size-Mapping
{'root' : 50 , '\usr' : 20, 'swap' : 1}
#OS-Version
[7.1, 7.2, 7.3, 7.4, 7.5, 7.6]

Как видите, первая строка находится в формате словаря, а вторая строка — в формате списка. Теперь, когда я читаю и сохраняю строки в переменных, Python не распознает формат. Это мой код, который я пытаюсь:

 f=open("C:\\Users\xyz\\Desktop\\Inputs.txt")
lines=f.readlines()
i = lines.index("#Drive-Size-Mapping\n")
di=dict()
di = lines[i+1]
print(di[0])
j = lines.index("#OS-Version\n")
list = lines[j+1]
print(list[0])

Код выше:

{ {

то есть он просто печатает элемент, который присутствует в первом индексе массива массива. Что я хочу, чтобы python интерпретировал эти переменные как словарь и список соответственно. Итак, если я сделаю print di["root"]

Мой код должен распознавать его как словарь и печатать как 50. И print(list[0]) должен распознать его как список и вывести 7.1.

Пожалуйста, дайте мне знать, как следует манипулировать строками файла, чтобы python интерпретировал их в том формате, в котором они на самом деле присутствуют?

Благодарю вас


person Brite Roy    schedule 16.04.2019    source источник
comment
di = lines[i+1] просто полностью перезаписывает di = dict(). index всегда возвращает только первый встреченный экземпляр, поэтому он также не подходит для повторяющихся данных.   -  person roganjosh    schedule 16.04.2019


Ответы (3)


Просто добавьте к приведенным выше ответам:

Использовать:

 ast.literal_eval()

Но удалите/замените "\" из ключей словаря, так как это может создать ошибку юникода в функции literal_eval()

Еще одна ошибка в коде, после преобразования в словарь нельзя делать d[0] так как словари не индексируются

person Siddharth    schedule 16.04.2019
comment
Хорошие моменты)! Побег-персонаж не слишком хорошо пойдет вниз. - person Jacques Gaudin; 16.04.2019
comment
Да, верно. Я использовал d[0] только для того, чтобы показать, что сейчас интерпретирует Python. После использования literal_eval(lines[j+1]) все работает нормально - person Brite Roy; 16.04.2019

Функция readlines делает то, что говорит: она читает строки. Мы с вами можем понять, что эти две строки — это словарь Python и список Python, но Python не может и не должен этого делать.

Мне кажется, что вы читаете настройки конфигурации из файла с исходным кодом Python. Более стандартный способ сделать это — использовать файл .ini. Посмотрите на модуль configparser.

person BoarGules    schedule 16.04.2019
comment
.ini файл? Что мне здесь не хватает? - person roganjosh; 16.04.2019
comment
ОП говорит, я хочу, чтобы Python интерпретировал эти переменные как словарь и список соответственно. Таким образом, литералы Python во входном файле должны интерпретироваться как данные. OP мог бы использовать для этого ast.literal_eval(), но я думаю, что это неправильный подход. - person BoarGules; 16.04.2019
comment
Хотя мой запрос выполнен с приведенным выше ответом literal_eval , но я также хотел бы узнать о configparser. Кажется, что-то с библиотекой ядра python и некоторыми манипуляциями со структурой данных. - person Brite Roy; 16.04.2019
comment
Хранение структурированных данных в виде литералов Python в текстовых файлах может показаться очевидным, но это тупиковый путь. Файлы конфигурации имеют более щадящий синтаксис, и configparser выдаст вам приличное сообщение об ошибке, если вы ошибетесь в синтаксисе, и даже в этом случае сделает все возможное, чтобы интерпретировать части, которые он может понять. ast.literal_eval просто скажет SyntaxError и оставит вас (или, что еще хуже, вашего пользователя) в неведении относительно того, что не так. Если вам необходимо сохранить структуры данных Python на диск (и иногда для этого есть очень веские причины), используйте pickle, а не фрагменты кода Python, хранящиеся в виде строк. - person BoarGules; 16.04.2019

Строки, которые вы получаете из файла, string. Если вы хотите преобразовать их в объекты dict или list, вы можете использовать literal_eval:

from ast import literal_eval

...
d = literal_eval(lines[i+1])
...
l = literal_eval(lines[i+1])

Если вы можете изменить формат входного файла, я бы рассмотрел его изменение в файл json для удобного хранения и загрузки ваших объектов с помощью модуль json.

person Jacques Gaudin    schedule 16.04.2019