'Python: Recursive function with keyword arguments with default values

I have a recursive function in my python script which looks something like this:

def recurse(nodes, keep_x=False, keep_y=False):
   for node in nodes:
      if not keep_x:
         node.pop('x', None)
      if not keep_y:
         node.pop('y', None)

      # Node may contain keys with lists of other nodes, so apply the function recursively
      for key in node.keys():
         if isinstance(node[key], list):
            node[key] = recurse(node[key], keep_x=keep_x, keep_y=keep_y)

This works but it doesn't seem very elegant to me to re-specify the keyword arguments in the recursive call.

Now if I would not have the default values I could do it like this:

def recurse(nodes, **kwargs):
   for node in nodes:
      if not kwargs['keep_x']:
         node.pop('x', None)
      if not kwargs['keep_y']:
         node.pop('y', None)

      # Node may contain keys with lists of other nodes, so apply the function recursively
      for key in node.keys():
         if isinstance(node[key], list):
            node[key] = recurse(node[key], **kwargs)

But this has the trouble that I have to add additional checks which keyword args actually got passed in or risk key errors.

What if I want to keep the default values for the keyword arguments? Is there a way to access the list of passed in keyword arguments (with default or overridden value) for the recursive call? Something like this (does not work in practice): recurse(node[key], **self.kwargs)



Solution 1:[1]

One simple change is to define an inner recursive function that can see delete_x and delete_y as non-local variables, avoiding the need to pass them to each recursive call.

def recurse(nodes, keep_x=False, keep_y=False):

    def helper(nodes):
       for node in nodes:
          if not keep_x:
             node.pop('x', None)
          if not keep_y:
             node.pop('y', None)
    
          for key in node.keys():
             if isinstance(node[key], list):
                node[key] = helper(node[key])

    return helper(nodes)

(Ignoring the issue of what helper should actually return, as the original recurse doesn't how a return value either.)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 chepner