我同意 mgilson 的分析。list
是一个可变类型并且list.append
是就地的。这是什么意思:
有两种类型:可变的和不可变的。
可变类型存在于内存中的相同位置,即使您更改它也是如此。例如,list
s 和s 是可变类型。dict
这意味着如果您创建一个list
并以某些方式更改它,它仍将位于内存中的同一位置。所以假设你创建了一个list
名为“myList”。假设这个列表在内存位置 0x9000 中。那么,doingmyList.append(0)
不会改变myList
内存中的位置。即使您这样做了myList[0] = 'a'
,该位置也不会改变 - 它仍将位于 0x9000。
当您尝试以任何方式更改它时,不可变类型将“移动”到不同的内存位置。str
s 和tuple
s 是不可变的。这就是您收到以下错误的原因:
>>> s = 'as'
>>> s[0] = 'b'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment
这意味着即使您定义s = 'as'
(假设s
现在位于内存地址 0x5000)并将其重新定义为s = 'af'
,内存中的位置s
也会发生变化。
现在,当您重新分配可变类型时,它在内存中的位置会发生变化。例如,
L = [1,2,3] # 说内存位置 0x4000 L = [5,6,7] # 内存位置不再是 0x4000
这就是list.append
“就地”属性发挥作用的地方。“list.append
就地”意味着将新元素添加到列表中而不创建新列表。这就是为什么list.append
没有返回值的原因,如下所示:
>>> L = [1,2,3]
>>> ret = L.append(4)
>>> print L
[1, 2, 3, 4]
>>> print ret
None
但是,如果您想创建一个新列表,您可以按如下方式进行:
>>> L = [1,2,3]
>>> ret = L + [4]
>>> print L
[1, 2, 3]
>>> print ret
[1, 2, 3, 4]
因此,在您的情况下发生的情况是,在两个递归调用(左和右)中,point
都将其附加到每个递归调用的列表中。这就是您获得重复值的原因。
您可以通过执行 mgilson 的建议来规避此问题,或者如果您是 lisp 粉丝(这是一个非常好的 lisp 问题),那么您可以使用该[1,2,3] + [4]
原理并执行此操作(未经测试,但应该可以):
def within_radius(self, point, radius, result=[]):
"""
Find all items in the tree within radius of point
"""
d = self.discriminator
temp = []
if in_circle(point, radius, self.data):
temp = [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:
temp += self.l_child.within_radius(point, radius, result)
if point[d] + radius > self.data[d] and self.r_child:
temp += self.r_child.within_radius(point, radius, result)
return result+temp
希望这可以帮助