'Convert camelCase to snakeCase
I have a dictionary something like this:
{
'firstName': 'abc',
'lastName': 'xyz',
'favoriteMovies': ['Star Wars', 'The lone ranger'],
'favoriteCountries': [
{'country': 'China', 'capitalCity': 'Beiging'},
{'country': 'India', 'capitalCity': 'New Delhi'}
]
}
I want to convert it to snake_case like the following
{
'first_name': 'abc',
'last_name': 'xyz',
'favorite_movies': ['Star Wars', 'The lone ranger'],
'favorite_countries': [
{'country': 'China', 'capital_city': 'Beiging'},
{'country': 'India', 'capital_city': 'New Delhi'}
]
}
The dictionary may be of any length depth.
My current solution is
import re
def convert_snake_case_to_camel_case(data):
required_dict = {}
for key, value in data.items():
if type(value) == str:
new_key = re.sub("([a-z0-9])([A-Z])", r"\1_\2", key).lower()
required_dict[new_key] = value
elif type(value) == list and all(list(map(lambda _: isinstance(_, str), value))):
new_key = re.sub("([a-z0-9])([A-Z])", r"\1_\2", key).lower()
required_dict[new_key] = value
elif type(value) == list and all(list(map(lambda _: isinstance(_, dict), value))):
new_key = re.sub("([a-z0-9])([A-Z])", r"\1_\2", key).lower()
required_dict[new_key] = list(filter(convert_snake_case_to_camel_case, value))
return required_dict
But I m not getting the expected result for the nested data.
Solution 1:[1]
data = {
'firstName': 'abc',
'lastName': 'xyz',
'favoriteMovies': ['Star Wars', 'The lone ranger'],
'favoriteCountries': [
{'country': 'China', 'capitalCity': 'Beiging'},
{'country': 'India', 'capitalCity': 'New Delhi'}
]
}
new_data = {}
for key, value in data.items():
new_key_list = ['_' + x.lower() if x.isupper() else x for x in key]
new_key = ''.join(new_key_list)
if isinstance(value[0],dict):
new_value = []
for item in value:
temp_dict = {}
for key2, value2 in item.items():
new_key_list = ['_' + x.lower() if x.isupper() else x for x in key2]
new_key = ''.join(new_key_list)
temp_dict[new_key] = value2
new_value.append(temp_dict)
new_data[new_key] = new_value
else:
new_data[new_key] = value
Output:
{'first_name': 'abc', 'last_name': 'xyz', 'favorite_movies': ['Star Wars', 'The lone ranger'], 'capital_city': [{'country': 'China', 'capital_city': 'Beiging'}, {'country': 'India', 'capital_city': 'New Delhi'}]}
Solution 2:[2]
Short recursive version:
import re
def to_snake(s):
return re.sub('([A-Z]\w+$)', '_\\1', s).lower()
def t_dict(d):
if isinstance(d, list):
return [t_dict(i) if isinstance(i, (dict, list)) else i for i in d]
return {to_snake(a):t_dict(b) if isinstance(b, (dict, list)) else b for a, b in d.items()}
data = {'firstName': 'abc', 'lastName': 'xyz', 'favoriteMovies': ['Star Wars', 'The lone ranger'], 'favoriteCountries': [{'country': 'China', 'capitalCity': 'Beiging'}, {'country': 'India', 'capitalCity': 'New Delhi'}]}
print(t_dict(data))
Output:
{'first_name': 'abc', 'last_name': 'xyz',
'favorite_movies': ['Star Wars', 'The lone ranger'],
'favorite_countries': [
{'country': 'China', 'capital_city': 'Beiging'},
{'country': 'India', 'capital_city': 'New Delhi'}
]
}
Solution 3:[3]
You could use regex
for this.
def camel_to_snake(str):
return re.sub(r'(?<!^)(?=[A-Z])', '_', str).lower()
Then build another recursive function which converts all the dictionary keys by using the above function.
Solution 4:[4]
Use the humps library
Example
import humps
humps.camelize('jack_in_the_box') # jackInTheBox
humps.decamelize('rubyTuesdays') # ruby_tuesdays
humps.pascalize('red_robin') # RedRobin
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Ajax1234 |
Solution 3 | Mihai Alexandru-Ionut |
Solution 4 | Phillip Kigenyi |