1

For an assignment I have to make a function that goes through a dictionary of people and finds those who are younger than the specified parameter. The dictionary is written in a way that each "person" has other people attached to them, which are their descendants, which can also have descendants etc. I need to make the programme work so that it goes through all of the descendants of a specified person and returns those who are younger than n. The problem is that I define a set() at the beginning of the function, and even though it gets filled afterwards, the value returned by the function is still set() because of its recursive nature. How do I fix this?

def funct(name, n):
    younger = set()
    for child in people[name]:
        if age[child] < n:
            younger.add(child)
        funct(child, n)
    return younger

and here's the data:

people = {
    "Adam": ["Matjaž", "Cilka", "Daniel", "Erik"],
    "Aleksander": [],
    "Alenka": [],
    "Barbara": [],
    "Cilka": [],
    "Daniel": ["Elizabeta", "Hans"],
    "Erik": [],
    "Elizabeta": ["Ludvik", "Jurij", "Barbara", "Herman", "Mihael"],
    "Franc": [],
    "Herman": ["Margareta"],
    "Hans": [],
    "Jožef": ["Alenka", "Aleksander", "Petra"],
    "Jurij": ["Franc", "Jožef"],
    "Ludvik": [],
    "Margareta": [],
    "Matjaž": ["Viljem"],
    "Mihael": [],
    "Petra": [],
    "Tadeja": [],
    "Viljem": ["Tadeja"],
}

age = {
    "Adam": 111, "Matjaž": 90, "Cilka": 88, "Daniel": 85, "Erik": 83,
    "Viljem": 58, "Tadeja": 20, "Elizabeta": 68, "Hans": 64, "Ludvik": 50,
    "Jurij": 49, "Barbara": 45, "Herman": 39, "Mihael": 32, "Franc": 30,
    "Jožef": 29, "Margareta": 3, "Alenka": 9, "Aleksander": 5, "Petra": 7}
John Y
  • 14,123
  • 2
  • 48
  • 72
x4nga
  • 37
  • 5

2 Answers2

1

One option is to pass the set around explicitly, creating it when not supplied (i.e. on the initial call):

def funct(name, n, younger=None):
    if younger is None:
        younger = set()
    for child in people[name]:
        if age[child] < n:
            younger.add(child)
        funct(child, n, younger)
    return younger

As to why I set the default younger=None, see "Least Astonishment" and the Mutable Default Argument.

I would also suggest not accessing people and age within the function by scope alone; make them explicit parameters.

Community
  • 1
  • 1
jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
  • Is it possible to do this without adding parameters to the function (The instructions for the assignment say: write the function funct(name, n),...) – x4nga Dec 18 '14 at 18:43
  • @x4nga another option would be to explicitly roll the `set` returned by the recursive call (which you *don't currently assign*) into `younger`. – jonrsharpe Dec 18 '14 at 18:44
0

Have younger hold the names of all descendants that meet the age requirement, not just the immediate children that meet the age requirement.

def funct(name, n):
    younger = set()
    for child in people[name]:
        if age[child] < n:
            younger.add(child)
        younger.update(funct(child, n))  # Changed line
    return younger
MackM
  • 2,906
  • 5
  • 31
  • 45