我有一本类似这样的字典:
{
'firstName': 'abc',
'lastName': 'xyz',
'favoriteMovies': ['Star Wars', 'The lone ranger'],
'favoriteCountries': [
{'country': 'China', 'capitalCity': 'Beiging'},
{'country': 'India', 'capitalCity': 'New Delhi'}
]
}
Run Code Online (Sandbox Code Playgroud)
我想将其转换为snake_case,如下所示
{
'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'}
]
}
Run Code Online (Sandbox Code Playgroud)
字典可以是任何长度深度。
我目前的解决方案是
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
Run Code Online (Sandbox Code Playgroud)
但我没有得到嵌套数据的预期结果。
Aja*_*234 11
短递归版本:
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()}
Run Code Online (Sandbox Code Playgroud)
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))
Run Code Online (Sandbox Code Playgroud)
输出:
{'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'}
]
}
Run Code Online (Sandbox Code Playgroud)
你可以用regex这个。
def camel_to_snake(str):
return re.sub(r'(?<!^)(?=[A-Z])', '_', str).lower()
Run Code Online (Sandbox Code Playgroud)
然后构建另一个递归函数,使用上述函数转换所有字典键。
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
Run Code Online (Sandbox Code Playgroud)
输出:
{'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'}]}
Run Code Online (Sandbox Code Playgroud)