2015-09-02 4 views
0

У меня есть словарь teacher, который содержит вложенные списки словарей. Я пытаюсь извлечь set имена для всех коллег и коллег из коллег Joe Bloggs, используя рекурсивную функцию.Извлечь набор значений из вложенных словарей/списков Python

teacher = {'age': 27, 
     'name': 'Joe Bloggs', 
     'colleagues': [{'age': 34, 
       'name': 'Tim Smith', 
       'colleagues': [{'age': 39, 
          'name': 'Linda Smith', 
          'colleagues': [{'age': 41, 
            'name': 'Belinda Barker', 
            'colleagues': []}]}, 
          {'age': 33, 
          'name': 'Kelly Brooker', 
          'colleagues': []}, 
          {'age': 44, 
          'name': 'Duncan Turnbull', 
          'colleagues': []}]}, 
       {'age': 29, 
        'name': 'Jenna French', 
        'colleagues': []}]} 

Желаемый результат:

{'Tim Smith', 'Linda Smith', 'Belinda Barker', 
'Kelly Brooker', 'Duncan Turnbull', 'Jenna French'} 

Обратите внимание на выход не должен быть в определенном порядке, так как это set. Как это часто бывает с рекурсивными функциями, трудно «добиться прогресса», фактически не найдя решение. До сих пор у меня есть рекурсивная функция, которая принимает два параметра, но не имеет ни малейшего представления о том, как настроить свою функцию для создания желаемых результатов:

def names(teacher, colleagues=None): 

ответ

2

Вы можете сделать это в комплекте понимании; цикл включает в себя все имена в colleagues списке плюс их рекурсивных имена коллеги:

def names(teacher): 
    return {name for c in teacher['colleagues'] for name in {c['name']} | names(c)} 

Вы могли бы также выразить это как объединение множества прямых имен и рекурсивные вызовы:

def names(teacher): 
    direct = {c['name'] for c in teacher['colleagues']} 
    return direct.union(*(names(c) for c in teacher['colleagues'])) 

Demo:

>>> def names(teacher): 
...  return {name for c in teacher['colleagues'] for name in {c['name']} | names(c)} 
... 
>>> names(teacher) 
{'Tim Smith', 'Belinda Barker', 'Kelly Brooker', 'Duncan Turnbull', 'Jenna French', 'Linda Smith'} 
>>> def names(teacher): 
...  direct = {c['name'] for c in teacher['colleagues']} 
...  return direct.union(*(names(c) for c in teacher['colleagues'])) 
... 
>>> names(teacher) 
{'Tim Smith', 'Belinda Barker', 'Linda Smith', 'Kelly Brooker', 'Duncan Turnbull', 'Jenna French'} 
Смежные вопросы