0

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)

6
  • 1
    Instead of if not kwargs['delete_x'] (which will give you a keyerror if the value isn't present), have you tried changing the check to 'delete_x' in kwargs (which will not)? Commented Mar 8, 2022 at 14:14
  • 1
    delete_x is an odd name for a parameter that removes x when it is false. Commented Mar 8, 2022 at 14:37
  • Should the second loop be inside the first loop? Commented Mar 8, 2022 at 14:43
  • 1
    Consider defining a recursive helper function inside recurse that closes over delete_x and delete_y. Commented Mar 8, 2022 at 14:44
  • @chepner you are right about delete_x, the variable/keyword arguments is named differently in the my actual code. Also right about the second loop, should be inside of the first. Updated the question to fix both of these. Commented Mar 8, 2022 at 15:28

1 Answer 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.)

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.