#python #python-3.x #dictionary #nested
#python #python-3.x #словарь #вложенный
Вопрос:
У меня также есть вложенный dict со списком dicts, и некоторые из моих ключей имеют специальные символы. Каков наилучший способ удалить эти специальные символы из ключей.
Ниже, что я попытался, работает с dicts of dicts, но как я могу расширить его, чтобы также позаботиться о list of dicts.
>>> a={"@pipeline": "start", "@args": "-vv", "@start": "1598331637", "@info": {"@pipeline_stage": "tasks","@taskbegin": [{"@task": "1", "@time": "1598331638"}, {"@task": "2", "@time": "1598331638"}, {"@task": "3", "@time": "1598331638"}]}}
>>> a
{'@pipeline': 'start', '@args': '-vv', '@start': '1598331637', '@info': {'@pipeline_stage': 'tasks', '@taskbegin': [{'@task': '1', '@time': '1598331638'}, {'@task': '2', '@time': '1598331638'}, {'@task': '3', '@time': '1598331638'}]}}
>>> def _clean_keys(d):
... return {''.join(filter(str.isalnum, k)): _clean_keys(v) for k, v in d.items()} if isinstance(d, dict) else d
...
>>> _clean_keys(a)
{'pipeline': 'start', 'args': '-vv', 'start': '1598331637', 'info': {'pipelinestage': 'tasks', 'taskbegin': [{'@task': '1', '@time': '1598331638'}, {'@task': '2', '@time': '1598331638'}, {'@task': '3', '@time': '1598331638'}]}}
>>>
Как вы можете видеть, список taskbegin не очищен.
Ответ №1:
Использование рекурсии
Пример:
a={"@pipeline": "start", "@args": "-vv", "@start": "1598331637", "@info": {"@pipeline_stage": "tasks","@taskbegin": [{"@task": "1", "@time": "1598331638"}, {"@task": "2", "@time": "1598331638"}, {"@task": "3", "@time": "1598331638"}]}}
def _clean_keys(d):
res = {}
if isinstance(d, dict):
for k, v in d.items():
k = ''.join(filter(str.isalnum, k))
if isinstance(v, list): #Check if type of value is list
res[k] = [_clean_keys(i) for i in v] #use recursion
else:
res[k]= _clean_keys(v)
else:
res = d
return res
print(_clean_keys(a))
Вывод:
{'args': '-vv',
'info': {'pipelinestage': 'tasks',
'taskbegin': [{'task': '1', 'time': '1598331638'},
{'task': '2', 'time': '1598331638'},
{'task': '3', 'time': '1598331638'}]},
'pipeline': 'start',
'start': '1598331637'}
Ответ №2:
Попробуйте это, работает нормально
Код
def clean_dict(val):
if type(val) == list:
return clean_list(val)
if type(val) == dict:
return {clean(k) : clean_dict(v) for k, v in val.items()}
return val
def clean_list(val):
return [clean_dict(v) for v in val]
def clean(val):
''.join([c for c in val if c.isalnum()])
Вывод
a={"@pipeline": "start", "@args": "-vv", "@start": "1598331637", "@info": {"@pipeline_stage": "tasks","@taskbe
gin": [{"@task": "1", "@time": "1598331638"}, {"@task": "2", "@time": "1598331638"}, {"@task": "3", "@time": "1
598331638"}]}}
clean_dict(a)
Out[8]:
{'pipeline': 'start',
'args': '-vv',
'start': '1598331637',
'info': {'pipelinestage': 'tasks',
'taskbegin': [{'task': '1', 'time': '1598331638'},
{'task': '2', 'time': '1598331638'},
{'task': '3', 'time': '1598331638'}]}}