String to Dictionary in Python

Convert a String representation of a Dictionary to a dictionary

You can use the built-in ast.literal_eval:

>>> import ast
>>> ast.literal_eval("{'muffin' : 'lolz', 'foo' : 'kitty'}")
{'muffin': 'lolz', 'foo': 'kitty'}

This is safer than using eval. As its own docs say:


>>> help(ast.literal_eval)
Help on function literal_eval in module ast:

literal_eval(node_or_string)
Safely evaluate an expression node or a string containing a Python
expression. The string or node provided may only consist of the following
Python literal structures: strings, numbers, tuples, lists, dicts, booleans,
and None.

For example:

>>> eval("shutil.rmtree('mongo')")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 1, in <module>
File "/opt/Python-2.6.1/lib/python2.6/shutil.py", line 208, in rmtree
onerror(os.listdir, path, sys.exc_info())
File "/opt/Python-2.6.1/lib/python2.6/shutil.py", line 206, in rmtree
names = os.listdir(path)
OSError: [Errno 2] No such file or directory: 'mongo'
>>> ast.literal_eval("shutil.rmtree('mongo')")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/opt/Python-2.6.1/lib/python2.6/ast.py", line 68, in literal_eval
return _convert(node_or_string)
File "/opt/Python-2.6.1/lib/python2.6/ast.py", line 67, in _convert
raise ValueError('malformed string')
ValueError: malformed string

String to Dictionary in Python

This data is JSON! You can deserialize it using the built-in json module if you're on Python 2.6+, otherwise you can use the excellent third-party simplejson module.

import json    # or `import simplejson as json` if on Python < 2.6

json_string = u'{ "id":"123456789", ... }'
obj = json.loads(json_string) # obj now contains a dict of the data

Convert string representation of dictionary to dictionary

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')"]}

Python: String to Dictionary

from ast import literal_eval
a_string = "{'platform_name': 'TSC2_commander', 'tracks': '52', 'time': '150'}"

a_dict = literal_eval(a_string)
print(a_dict['platform_name'])

Output:

TSC2_commander

Simple way to convert a string to a dictionary

This works for me:

# get all the items
matches = re.findall(r'\w+=".+?"', s) + re.findall(r'\w+=[\d.]+',s)

# partition each match at '='
matches = [m.group().split('=', 1) for m in matches]

# use results to make a dict
d = dict(matches)

How can I convert string to dict or list?

ast.literal_eval parses 'abstract syntax trees.' You nearly have json there, for which you could use json.loads, but you need double quotes, not single quotes, for dictionary keys to be valid.

import ast

result = ast.literal_eval("{'a': 1, 'b': 2}")
assert type(result) is dict

result = ast.literal_eval("[1, 2, 3]")
assert type(result) is list

As a plus, this has none of the risk of eval, because it doesn't get into the business of evaluating functions. eval("subprocess.call(['sudo', 'rm', '-rf', '/'])") could remove your root directory, but ast.literal_eval("subprocess.call(['sudo', 'rm', '-rf', '/'])") fails predictably, with your file system intact.

python 3 dictionary key to a string and value to another string

Use dict.items():

You can use dict.items() (dict.iteritems() for python 2), it returns pairs of keys and values, and you can simply pick its first.

>>> d = { 'a': 'b' }
>>> key, value = list(d.items())[0]
>>> key
'a'
>>> value
'b'

I converted d.items() to a list, and picked its 0 index, you can also convert it into an iterator, and pick its first using next:

>>> key, value = next(iter(d.items()))
>>> key
'a'
>>> value
'b'

Use dict.keys() and dict.values():

You can also use dict.keys() to retrieve all of the dictionary keys, and pick its first key. And use dict.values() to retrieve all of the dictionary values:

>>> key = list(d.keys())[0]
>>> key
'a'
>>> value = list(d.values())[0]
>>> value
'b'

Here, you can use next(iter(...)) too:

>>> key = next(iter(d.keys()))
>>> key
'a'
>>> value = next(iter(d.values()))
'b'

Ensure getting a str:

The above methods don't ensure retrieving a string, they'll return whatever is the actual type of the key, and value. You can explicitly convert them to str:

>>> d = {'some_key': 1}
>>> key, value = next((str(k), str(v)) for k, v in d.items())
>>> key
'some_key'
>>> value
'1'
>>> type(key)
<class 'str'>
>>> type(value)
<class 'str'>

Now, both key, and value are str. Although actual value in dict was an int.

Disclaimer: These methods will pick first key, value pair of dictionary if it has multiple key value pairs, and simply ignore others. And it will NOT work if the dictionary is empty. If you need a solution which simply fails if there are multiple values in the dictionary, @SylvainLeroux's answer is the one you should look for.

How to search if dictionary value contains certain string with Python

I am a bit late, but another way is to use list comprehension and the any function, that takes an iterable and returns True whenever one element is True :

# Checking if string 'Mary' exists in the lists of the dictionary values
print any(any('Mary' in s for s in subList) for subList in myDict.values())

If you wanna count the number of element that have "Mary" in them, you can use sum():

# Number of sublists containing 'Mary'
print sum(any('Mary' in s for s in subList) for subList in myDict.values())

# Number of strings containing 'Mary'
print sum(sum('Mary' in s for s in subList) for subList in myDict.values())

From these methods, we can easily make functions to check which are the keys or values matching.

To get the keys containing 'Mary':

def matchingKeys(dictionary, searchString):
return [key for key,val in dictionary.items() if any(searchString in s for s in val)]

To get the sublists:

def matchingValues(dictionary, searchString):
return [val for val in dictionary.values() if any(searchString in s for s in val)]

To get the strings:

def matchingValues(dictionary, searchString):
return [s for s i for val in dictionary.values() if any(searchString in s for s in val)]

To get both:

def matchingElements(dictionary, searchString):
return {key:val for key,val in dictionary.items() if any(searchString in s for s in val)}

And if you want to get only the strings containing "Mary", you can do a double list comprehension :

def matchingStrings(dictionary, searchString):
return [s for val in dictionary.values() for s in val if searchString in s]


Related Topics



Leave a reply



Submit