#python
#python
Вопрос:
С четырьмя словарями grandpa
, dad
, son_1
и son_2
:
grandpa = {'name': 'grandpa', 'parents': []}
dad = {'name': 'dad', 'parents': ['grandpa']}
son_1 = {'name': 'son_1', 'parents': ['dad']}
son_2 = {'name': 'son_2', 'parents': ['dad']}
relatives = [son_1, grandpa, dad, son_2]
Я хочу написать функцию, которая сортирует всех этих родственников в «обратном» порядке.
Таким образом, вместо parents
там будет children
использоваться list. Самый старый grandpa
был бы на верхнем уровне result
словаря, dad
был бы ниже со своим children
списком, хранящим son_1
и son_2
:
def sortRelatives(relatives):
# returns a resulted dictionary:
# logic
result = sortRelatives(relatives)
print result
Что бы выводило:
result = {'name': 'grandpa',
'children': [
{'name': 'dad',
'children': [{'name': 'son_1', 'children': [] },
{'name': 'son_2', 'children': [] }] }
]
}
Как заставить sortRelatives
функцию выполнять такую сортировку?
Комментарии:
1.
The oldest grandpa would be on the top level of result dictionary
По какому полю вы сортируете? Например, возраст не включен в ваш словарь.2. @ScottSkiles Тот, у которого пусто
'parents'
, я полагаю3. В этом примере имена уникальны, и существует только один родительский элемент. Разумно ли это предположение, или ваши фактические данные сильно отличаются от того, чем вы поделились здесь?
4. Я думаю, что вопрос нуждается в существенном уточнении… (Однако я не понизил голос)
5. Это не называется сортировкой. Это своего рода поиск или сопоставление. Я не понимаю, почему это должно быть рекурсивным? Откуда взялось это требование? Это домашнее задание?
Ответ №1:
Что я считаю жизнеспособным, но простым решением, так это сначала создать дочерний словарь, который будет сопоставлять имена пользователей с их дочерними элементами. Затем мы можем использовать эту новую структуру данных для построения выходных данных:
from collections import defaultdict
def children(relatives):
children = defaultdict(list)
for person in relatives:
for parent in person['parents']:
children[parent].append(person)
return children
Другой инструмент, который мы можем использовать, — это функция, которая найдет корень нашей генеалогии:
def genealogy_root(relatives):
for person in relatives:
if not person['parents']:
return person
raise TypeError("This doesn't look like a valid genealogy.")
Это поможет нам определить местонахождение человека, у которого нет родителя, и, следовательно, он будет корнем нашего генеалогического дерева. Теперь, когда у нас есть все необходимые инструменты, нам просто нужно создать выходные данные:
def build_genealogy(relatives):
relatives_children = children(relatives)
def sub_genealogy(current_person):
name = current_person['name']
return dict(
name=name,
children=[sub_genealogy(child) for child in relatives_children[name]]
)
root = genealogy_root(relatives)
return sub_genealogy(root)
result = build_genealogy(relatives)
print(result)
Какие результаты:
{
'name': 'grandpa', 'children': [
{'name': 'dad', 'children': [
{'name': 'son_1', 'children': []},
{'name': 'son_2', 'children': []}
]}
]
}
Обратите внимание, что, как я сказал в комментариях, это работает только потому, что нет дубликатов имен. Если несколько пользователей используют одно и то же имя, вам потребуется лучшая структура данных в качестве входных данных. Например, вы можете захотеть иметь что-то вроде:
grandpa = {'name': 'grandpa', 'parents': []}
dad = {'name': 'dad', 'parents': [grandpa]}
son_1 = {'name': 'son_1', 'parents': [dad]}
son_2 = {'name': 'son_2', 'parents': [dad]}
relatives = [grandpa, dad, son_1, son_2]