convert string to dictionary in python (passing dict as plain str)
Question:
I have a string
test_string = "{Team A: [service1, service2], Team B: [service3, service4], Team 3: [service5, service6] }"
I want to know a way to convert this into a dictionary in python
Answers:
You can use the ast module
import ast
test_string = "{Team A: [service1, service2], Team B: [service3, service4], Team 3: [service5, service6] }"
# Wrap the string in curly braces to make it a valid dictionary literal
test_string = "{" + test_string + "}"
# Use ast.literal_eval to convert the string to a dictionary
result_dict = ast.literal_eval(test_string)
print(result_dict)
Output:
{'Team A': ['service1', 'service2'], 'Team B': ['service3', 'service4'], 'Team 3': ['service5', 'service6']}
Note that in the original string, the dictionary keys and values are not surrounded by quotes, so they will be interpreted as variable names. the keys are converted to strings and the values are assumed to be variables that are not defined in the current scope. If you want the dictionary keys and values to be treated as strings, you should surround them with quotes in the original string.
You can use the eval() function to convert the string into a dictionary.
Here’s an example:
test_string = '{"Team A": ["service1", "service2"], "Team B": ["service3", "service4"], "Team 3": ["service5", "service6"] }'
dictionary = eval(test_string)
print(dictionary)
Output:
{'Team A': ['service1', 'service2'], 'Team B': ['service3', 'service4'], 'Team 3': ['service5', 'service6']}
The yaml
library is able to load this. It will turn all your items into strings, unless they are parseable in python:
import yaml
test_string = "{Team A: [service1, service2], Team B: [service3, service4], Team 3: [service5, service6] }"
parsed_dict = yaml.safe_load(test_string)
print(parsed_dict)
Outputs:
{'Team A': ['service1', 'service2'], 'Team B': ['service3', 'service4'], 'Team 3': ['service5', 'service6']}
Here is another example of what it may parse:
>>> yaml.safe_load("{a b c : [123, 99.0, a string, another]}")
{'a b c': [123, 99.0, 'a string', 'another']}
You should be aware that YAML (and so parsing with YAML) is a very complicated format that can have a lot of unintended effects. If possible you should find out if you can output JSON or some other serialised data from your Azure DevOps pipeline.
You can just use regex. There is an example on the bottom on how to use specific dictionary parts
import re
test_string = "{Team A: [service1, service2], Team B: [service3, service4], Team 3: [service5, service6] }"
key_regex = r'([w ]+):' #matches key
value_regex = r'[([^]]+)]' #matches opening bracket then matches characters that are not a closing bracket and then matches closing bracket
pairs = re.findall(f'{key_regex}s*{value_regex}', test_string) #returns all non-overlapping matches of re in test_string
dictionary = {}
for key, value in pairs:
key = key.strip()
value = value.split(', ')
dictionary[key] = value
print(f"Full: {dictionary}") #outputs: {'Team A': ['service1', 'service2'], 'Team B': ['service3', 'service4'], 'Team 3': ['service5', 'service6']}
print(dictionary['Team A']) #outputs: ['service1', 'service2']
print(dictionary['Team B']) #outputs: ['service3', 'service4']
print(dictionary['Team 3']) #outputs: ['service5', 'service6']
You could use a regular expression to break down the string into key and value substrings. Then build the dictionary by stripping the delimiters out and using split to convert the values to lists:
import re
S = "{Team A: [service1, service2], Team B: [service3, service4], Team 3: [service5, service6] }"
parts = filter(bool,re.split(r"([{,] *(?:[^,]+?:))",S))
D = {k.strip("{, :"):v.strip(" [],}").split(", ") for k,v in zip(parts,parts)}
print(D)
{'Team A': ['service1', 'service2'],
'Team B': ['service3', 'service4'],
'Team 3': ['service5', 'service6']}
The parts
variable is an iterator on the substrings that is fed to zip twice to pair up consecutive substrings into a key and value
output of pairs (re.split with a capture group in the pattern includes separators in the output):
'{Team A:', ' [service1, service2]',
', Team B:', ' [service3, service4]',
', Team 3:', ' [service5, service6] }'
I have a string
test_string = "{Team A: [service1, service2], Team B: [service3, service4], Team 3: [service5, service6] }"
I want to know a way to convert this into a dictionary in python
You can use the ast module
import ast
test_string = "{Team A: [service1, service2], Team B: [service3, service4], Team 3: [service5, service6] }"
# Wrap the string in curly braces to make it a valid dictionary literal
test_string = "{" + test_string + "}"
# Use ast.literal_eval to convert the string to a dictionary
result_dict = ast.literal_eval(test_string)
print(result_dict)
Output:
{'Team A': ['service1', 'service2'], 'Team B': ['service3', 'service4'], 'Team 3': ['service5', 'service6']}
Note that in the original string, the dictionary keys and values are not surrounded by quotes, so they will be interpreted as variable names. the keys are converted to strings and the values are assumed to be variables that are not defined in the current scope. If you want the dictionary keys and values to be treated as strings, you should surround them with quotes in the original string.
You can use the eval() function to convert the string into a dictionary.
Here’s an example:
test_string = '{"Team A": ["service1", "service2"], "Team B": ["service3", "service4"], "Team 3": ["service5", "service6"] }'
dictionary = eval(test_string)
print(dictionary)
Output:
{'Team A': ['service1', 'service2'], 'Team B': ['service3', 'service4'], 'Team 3': ['service5', 'service6']}
The yaml
library is able to load this. It will turn all your items into strings, unless they are parseable in python:
import yaml
test_string = "{Team A: [service1, service2], Team B: [service3, service4], Team 3: [service5, service6] }"
parsed_dict = yaml.safe_load(test_string)
print(parsed_dict)
Outputs:
{'Team A': ['service1', 'service2'], 'Team B': ['service3', 'service4'], 'Team 3': ['service5', 'service6']}
Here is another example of what it may parse:
>>> yaml.safe_load("{a b c : [123, 99.0, a string, another]}")
{'a b c': [123, 99.0, 'a string', 'another']}
You should be aware that YAML (and so parsing with YAML) is a very complicated format that can have a lot of unintended effects. If possible you should find out if you can output JSON or some other serialised data from your Azure DevOps pipeline.
You can just use regex. There is an example on the bottom on how to use specific dictionary parts
import re
test_string = "{Team A: [service1, service2], Team B: [service3, service4], Team 3: [service5, service6] }"
key_regex = r'([w ]+):' #matches key
value_regex = r'[([^]]+)]' #matches opening bracket then matches characters that are not a closing bracket and then matches closing bracket
pairs = re.findall(f'{key_regex}s*{value_regex}', test_string) #returns all non-overlapping matches of re in test_string
dictionary = {}
for key, value in pairs:
key = key.strip()
value = value.split(', ')
dictionary[key] = value
print(f"Full: {dictionary}") #outputs: {'Team A': ['service1', 'service2'], 'Team B': ['service3', 'service4'], 'Team 3': ['service5', 'service6']}
print(dictionary['Team A']) #outputs: ['service1', 'service2']
print(dictionary['Team B']) #outputs: ['service3', 'service4']
print(dictionary['Team 3']) #outputs: ['service5', 'service6']
You could use a regular expression to break down the string into key and value substrings. Then build the dictionary by stripping the delimiters out and using split to convert the values to lists:
import re
S = "{Team A: [service1, service2], Team B: [service3, service4], Team 3: [service5, service6] }"
parts = filter(bool,re.split(r"([{,] *(?:[^,]+?:))",S))
D = {k.strip("{, :"):v.strip(" [],}").split(", ") for k,v in zip(parts,parts)}
print(D)
{'Team A': ['service1', 'service2'],
'Team B': ['service3', 'service4'],
'Team 3': ['service5', 'service6']}
The parts
variable is an iterator on the substrings that is fed to zip twice to pair up consecutive substrings into a key and value
output of pairs (re.split with a capture group in the pattern includes separators in the output):
'{Team A:', ' [service1, service2]',
', Team B:', ' [service3, service4]',
', Team 3:', ' [service5, service6] }'