I have a dictionary, which is written in .txt file in this way(picture)enter image description here
How can I input it in my programm?
Thanks!
Tried a normal way of inputting from a file but obviously it didnt work. json doesnt work with sets :c
I have a dictionary, which is written in .txt file in this way(picture)enter image description here
How can I input it in my programm?
Thanks!
Tried a normal way of inputting from a file but obviously it didnt work. json doesnt work with sets :c
I've retyped the contents of your file, let's load it first:
with open("weird_dictionary.txt", 'r') as f:
weird_dict = f.read()
print(weird_dict)
0, {1, 2}
1, {0, 3, 4}
2, {0}
3, {1}
4, {2, 3}
No way this is a dictionary. Not in this universe at least.
We can assume that the first digit in each line is a key and keeping in mind your:
json doesnt work with sets
We may assume that contents within curly braces are sets.
Okay.
One way to cast this mess into a dictionary with sets is to use eval()
.
But we'll need to prepare this string to something that can be evaluated without an error. I'll use regex for this.
import re
s = '{' + re.sub(r'(?<=\d),(?=\s{)', ':', weird_dict) + '}'
s = re.sub(r'\n', ', ', s)
print(s)
{0: {1, 2}, 1: {0, 3, 4}, 2: {0}, 3: {1}, 4: {2, 3}}
Now this is a valid dictionary with sets.
,
to :
to have a valid dictionary syntax
(?<=\d)
is a positive lookbehind(?=\s{)
is a positive lookahead\n
new line is substituted to comma and spaceNow you may do eval(s)
but a safer option would be to use literal_eval
:
from ast import literal_eval
e = literal_eval(s)
print(e)
print(type(e))
print(type(e[1]))
{0: {1, 2}, 1: {0, 3, 4}, 2: {0}, 3: {1}, 4: {2, 3}}
<class 'dict'>
<class 'set'>
Generally as a rule of thumb you should remember, never use eval
in any it's implementation when there are other options to parse.
And there is one, yaml works fine with sets. Json does not, you are right.
Look at yaml syntax for sets, we'll once again have to adopt your mess to yaml format, this time it will require some parsing and this can be done without regex using python syntax alone:
s = ''
for i in weird_dict.split('\n'):
s += i[:i.find('{')].replace(',',':') + '!!set\n'
for j in i[i.find('{')+1:-1].split(', '):
s += ' ? {}\n'.format(j)
print(s)
Or one liner:
s = '\n'.join([i[:i.find('{')-1]+' !!set\n'+'\n'.join([' ? '+j for j in i[i.find('{')+1:-1].split(', ')]) for i in weird_dict.split('\n')]).replace(',',':')
print(s)
0: !!set
? 1
? 2
1: !!set
? 0
? 3
? 4
2: !!set
? 0
3: !!set
? 1
4: !!set
? 2
? 3
Now this is an absolutely valid syntax for yaml, and yaml is much safer to cast string to data structures compared to eval()
:
import yaml
e = yaml.safe_load(s)
print(e)
print(type(e))
print(type(e[1]))
{0: {1, 2}, 1: {0, 3, 4}, 2: {0}, 3: {1}, 4: {2, 3}}
<class 'dict'>
<class 'set'>
As a final option you may just parse the contents straight into dict
:
my_dict = {}
for i in weird_dict.split('\n'):
my_dict[int(i[0])] = set([int(j) for j in i[i.find('{')+1:-1].split(', ')])
print(my_dict)
Or one liner:
my_dict = {int(i[0]): set([int(j) for j in i[i.find('{')+1:-1].split(', ')]) for i in weird_dict.split('\n')}
print(my_dict)
{0: {1, 2}, 1: {0, 3, 4}, 2: {0}, 3: {1}, 4: {2, 3}}