Конвертировать camelCase в snakeCase - PullRequest
0 голосов
/ 10 февраля 2020

У меня есть словарь примерно такой:

{
     'firstName': 'abc',
     'lastName': 'xyz',
     'favoriteMovies': ['Star Wars', 'The lone ranger'],
     'favoriteCountries': [
          {'country': 'China', 'capitalCity': 'Beiging'},
          {'country': 'India', 'capitalCity': 'New Delhi'}
     ]
}

Я хочу преобразовать его в 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'}
     ]
}  

Словарь может иметь любую глубину длины.

Мое текущее решение -

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

Но я не получаю ожидаемый результат для вложенных данных.

Ответы [ 3 ]

2 голосов
/ 10 февраля 2020

Вы можете использовать regex для этого.

def camel_to_snake(str):
   return re.sub(r'(?<!^)(?=[A-Z])', '_', str).lower()

Затем создать другую рекурсивную функцию, которая преобразует весь словарь keys , используя вышеуказанную функцию.

0 голосов
/ 10 февраля 2020

Короткая рекурсивная версия:

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))

Вывод:

{'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'}
  ]
}
0 голосов
/ 10 февраля 2020
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

Выход:

{'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'}]}
...