I'm trying to teach myself about data structures, and I'm implementing a k-d tree in Python. I have a method to search for points in the tree within a certain radius of one point in my k-d tree class:
def within_radius(self, point, radius, result=[]):
"""
Find all items in the tree within radius of point
"""
d = self.discriminator
if in_circle(point, radius, self.data):
result.append(self.data)
# Check whether any of the points in the subtrees could be
# within the circle
if point[d] - radius < self.data[d] and self.l_child:
result.append(self.l_child.within_radius(point, radius, result))
if point[d] + radius > self.data[d] and self.r_child:
result.append(self.r_child.within_radius(point, radius, result))
return result
It works, but the list it returns is pretty funky, with duplicate values from the recursive calls with result
. What is a good way of "accumulating" the values returned from a tree recursion into a list? I've been thinking about it for a while but I can't really see how.
I'm not sure if this is the most clean way to do it, but whenever I do recursion like this, I often add a keyword argument which is the list that is to be returned. That way, when I modify the list, I'm always modifying to the same list:
def recurse(max, _output=None):
if _output is None:
_output = []
#do some work here, add to your list
_output.append(max)
if max <= 0: #Some condition where the recursion stops
return _output
else: #recurse with new arguments so that we'll stop someday...
return recurse(max-1, _output=_output)
This works because when the stop condition is True
, the _output
list is returned and passed all the way back up the stack.
I use an underscored variable name to indicate that it is meant to be used only within the function itself. This is a slight extension to the normal way underscore-prefixed variables are used (in classes to indicate a variable is "private"), but I think it gets the point across...
Note that this isn't very different from what you have. However, with your version, result
will persist between calls since result = []
is evaluated when the function is created, not when it is called. Also, your version is appending the return value (which is the list itself). This gets quite convoluted when you think about the list holding multiple references to itself ...