Synt
Synt

Reputation: 13

Converting a string into a dictionary using literal_eval

The whole idea of the program is to read data from a text file (which was saved as a string from a dictionary using a 'for' loop) then inserting that content back into the dictionary. After that, the program continues to ask for input (name & number) and adding it into the dictionary.

I've used the "ast.literal_eval" to convert the string(s) into a dictionary, like so:

import ast

f = open("resources/contacts.txt", "r+")
contactlist = f.read() # converting the string into a dictionary starts here
contactlist = ast.literal_eval(contactlist) # and ends here
print(contactlist) # for debugging purposes 

answer = 'again'

while answer == 'again':
    contact = input("enter a contact name: ")
    contactnum = input("enter the contact's number: ")
    contactlist[contact]= contactnum
    answer = input("again or stop: ")

f = open("resources/contacts.txt", "r+")

for item in contactlist:
    f.write(item + contactlist[item])

print(f.read())
f.close()

This throws the error:

Traceback (most recent call last):
  File "D:\Code\Python\Projects\Contacts.py", line 5, in <module>
    contactlist = ast.literal_eval(contactlist)
  File "D:\Code\Python\PYTHON\lib\ast.py", line 84, in literal_eval
    return _convert(node_or_string)
  File "D:\Code\Python\PYTHON\lib\ast.py", line 83, in _convert
raise ValueError('malformed node or string: ' + repr(node))
ValueError: malformed node or string: <_ast.Name object at 0x02F52B10>

From what I've found on this error, it doesn't accept any value types outside a specific range, but mine should be accepted. I'm lost, I've searched through dozens of related threads but can't find a fix.

Upvotes: 1

Views: 1957

Answers (1)

jonrsharpe
jonrsharpe

Reputation: 122106

You have a dictionary like:

{'Name': '00000000'}

When you write it out:

for item in contactlist:
    f.write(item + contactlist[item])

Your file is:

Name00000000

You cannot parse that with ast.literal_eval - it no longer "looks like" a Python dictionary. Instead, write out the string representation of the whole dictionary:

f.write(str(contactlist))

then the content of your file actually looks like a dictionary:

{'Name': '00000000'}

and you can evaluate it back to a dictionary.

Alternatively, look into e.g. pickle, which can create a flat file representation of arbitrary Python data structures, or json, which can handle e.g. lists and dictionaries of integers, strings and floats.

Upvotes: 3

Related Questions