Is their a way to convert strings illustrating dictionaries into some dictionary in Python.
E.g. I want to convert the string:
s = "{1:p→q,2: ¬q,3: ¬ (¬p),4: ¬p,5:[edge(¬p,¬p∧ ¬ (¬p)),edge(¬ (¬p),¬p∧ ¬ (¬p)),rule('∧I')],6:[edge(¬p,p),edge(¬p∧ ¬ (¬p),p),rule('¬E')],7:[edge(p,q),edge(p→q,q),rule('→E')],8:[edge(q,q∧ ¬q),edge(¬q,q∧ ¬q),rule('∧I')],9:[edge(¬ (¬p),¬p),edge(q∧ ¬q,¬p),rule('¬E')]}"
into some dictionary of following form:
d = {1:'p→q',2: '¬q',3: '¬ (¬p)',4: '¬p',5:['edge(¬p,¬p∧ ¬ (¬p))','edge(¬ (¬p),¬p∧ ¬ (¬p))','rule("∧I")'],6:['edge(¬p,p)','edge(¬p∧ ¬ (¬p),p)','rule("¬E")'],7:['edge(p,q)','edge(p→q,q)','rule("→E")'],8:['edge(q,q∧ ¬q)','edge(¬q,q∧ ¬q)','rule("∧I")'],9:['edge(¬ (¬p),¬p)','edge(q∧ ¬q,¬p)','rule("¬E")']}
I've tried json.loads(s), but unfortunately it needs some string which already has the quotation marks at the values of the dictionary itself.
I hope some similar solution is possible to solve that problem.
Remark: Strings like s
I generate from some Prolog dictionary.
CodePudding user response:
Here is a way to do it that works on your example, but would fail if things were more nested or whatever. In this case, I would rather recommend trying to get the data in a more manageable format, like JSON, rather than try to write a parser that would work in any possible case.
It's a rather crude way of parsing the string by splitting it with regex:
s = "{1:p→q,2: ¬q,3: ¬ (¬p),4: ¬p,5:[edge(¬p,¬p∧ ¬ (¬p)),edge(¬ (¬p),¬p∧ ¬ (¬p)),rule('∧I')],6:[edge(¬p,p),edge(¬p∧ ¬ (¬p),p),rule('¬E')],7:[edge(p,q),edge(p→q,q),rule('→E')],8:[edge(q,q∧ ¬q),edge(¬q,q∧ ¬q),rule('∧I')],9:[edge(¬ (¬p),¬p),edge(q∧ ¬q,¬p),rule('¬E')]}"
import re
# We split on optional ",", a number and ":"
split = re.split(r',?(\d ):', s[1:-1])
# ['', '1', 'p→q', '2', ' ¬q', '3', ' ¬ (¬p)' ...]
# Convert the numbers to int
split[1::2] = [int(n) for n in split[1::2]]
# We create a dict with the numbers as keys
d = dict(zip(split[1::2], split[2::2]))
# The values starting with "[" need to be converted to lists
for k, v in d.items():
if v.startswith('['):
# We split on "edge" or "rule"
split = re.split(',?(edge|rule)',v[1:-1])
# and create the list, joining each separator with what follows it
d[k] = list(''.join(parts) for parts in zip(split[1::2], split[2::2]))
print(d)
Output:
{1: 'p→q',
2: ' ¬q',
3: ' ¬ (¬p)',
4: ' ¬p',
5: ['edge(¬p,¬p∧ ¬ (¬p))', 'edge(¬ (¬p),¬p∧ ¬ (¬p))', "rule('∧I')"],
6: ['edge(¬p,p)', 'edge(¬p∧ ¬ (¬p),p)', "rule('¬E')"],
7: ['edge(p,q)', 'edge(p→q,q)', "rule('→E')"],
8: ['edge(q,q∧ ¬q)', 'edge(¬q,q∧ ¬q)', "rule('∧I')"],
9: ['edge(¬ (¬p),¬p)', 'edge(q∧ ¬q,¬p)', "rule('¬E')"]}
CodePudding user response:
You can use a library I wrote, called tocode
read the doc and example here:
- Install it using:
pip install tocode==0.1.3
- Import it and use it:
import tocode
# Example
s = "{this: 5, (Alex, Daniel): are good boys, (5, 4): 8.5}"
s = tocode.literal_eval(s, no_string_quotation=True)
Output:
{'this': 5, ('Alex', 'Daniel'): 'are good boys', (5, 4): 8.5}
CodePudding user response:
This code may help you.
Finally, After a long time using my small brain I got the same output as you want using pure python without using any module.
s = "{1:p→q,2: ¬q,3: ¬ (¬p),4: ¬p,5:[edge(¬p,¬p∧ ¬ (¬p)),edge(¬ (¬p),¬p∧ ¬ (¬p)),rule('∧I')],6:[edge(¬p,p),edge(¬p∧ ¬ (¬p),p),rule('¬E')],7:[edge(p,q),edge(p→q,q),rule('→E')],8:[edge(q,q∧ ¬q),edge(¬q,q∧ ¬q),rule('∧I')],9:[edge(¬ (¬p),¬p),edge(q∧ ¬q,¬p),rule('¬E')]}"
s = s[1:-1].split(':')
d = {}
def return_value(value):
if value.startswith('['):
l = value
l = l[1:-1].split('),')
for i in range(len(l)-1):
l[i] = l[i] ')'
value = l
return value
for v in range(len(s)):
if v != len(s)-2:
try:
value = s[v 1][:-2]
value = return_value(value)
d[int(s[v][-1])]=value
except:
pass
else:
value = s[v 1]
value = return_value(value)
value[0]=value[0] value[1]
del value[1]
d[int(s[v][-1])]=value
print(d)
Output
{1: 'p→q', 2: ' ¬q', 3: ' ¬ (¬p)', 4: ' ¬p', 5: ['edge(¬p,¬p∧ ¬ (¬p))', 'edge(¬ (¬p)', '¬p∧ ¬ (¬p))', "rule('∧I')"], 6: ['edge(¬p,p)', 'edge(¬p∧ ¬ (¬p)', 'p)', "rule('¬E')"], 7: ['edge(p,q)', 'edge(p→q,q)', "rule('→E')"], 8: ['edge(q,q∧ ¬q)', 'edge(¬q,q∧ ¬q)', "rule('∧I')"], 9: ['edge(¬ (¬p)¬p)', 'edge(q∧ ¬q,¬p)', "rule('¬E'"]}