#python
#python
Вопрос:
У меня есть следующие данные
a = {'globe': {'first_entry': 0,
'first_messanger': 100,
'galaxy': 7},
'earth': {'secondary_messanger': 9,
'earth_forecast': {'avg_temp': 60,
'zip_code': 10001,
'city_name': 'New York',
'forecast': [{'day': 'Monday',
'temp': '70'},
{'day': 'Tuesday',
'temp': '71'},
{'day': 'Wednesday',
'temp': '60'}]}}}
Я пробовал с помощью кода
def parsingvalue(b):
lst = []
for key, value in b.items():
if isinstance(value, dict):
tmp = value.keys()
for i in tmp:
lst.append(i)
lst.append (key)
print (sorted(lst))
parsingvalue (a)
С помощью этого кода мой вывод — ['earth', 'earth_forecast', 'first_entry', 'first_messanger', 'galaxy', 'globe', 'secondary_messanger']
Вывод отсутствует — 'avg_temp', 'zip_code', 'city_name', 'forecast', 'day', 'temp'
Вопрос: Как я могу улучшить код, чтобы вывод также включал отсутствующие ключевые элементы?
Ответ №1:
Вам нужно вызвать функцию рекурсивно, поскольку они состоят из нескольких слоев:
def get_all_keys(d, res=None):
if res is None:
res = []
for k in d:
res.append(k)
if isinstance(d[k], dict):
get_all_keys(d[k], res)
if isinstance(d[k], list):
for i in d[k]:
if isinstance(i, dict):
get_all_keys(i, res)
return res
ret = get_all_keys(a)
list(set(ret))
Дает:
['forecast',
'secondary_messanger',
'first_entry',
'zip_code',
'day',
'galaxy',
'first_messanger',
'temp',
'earth',
'globe',
'city_name',
'avg_temp',
'earth_forecast']
Комментарии:
1. @Z Li — Большое спасибо. Это работает отлично.
Ответ №2:
Почти то же решение, что и у @z-li, который использует рекурсивный трюк, но только с одним тестом на экземпляре dict, используя генератор вместо передачи списка, и немного более надежный, поскольку он не предполагает, что ввод является dict:
def get_all_keys(d):
if isinstance(d, dict):
yield from d.keys()
yield from get_all_keys(list(d.values()))
elif isinstance(d, list):
for v in d:
yield from get_all_keys(v)
с
ret = get_all_keys(a)
list(set(ret))
дайте
['first_messanger', 'secondary_messanger', 'galaxy', 'earth_forecast', 'globe', 'forecast', 'day', 'zip_code', 'avg_temp', 'city_name', 'temp', 'earth', 'first_entry']