我同意mgilson的分析。list是可变类型,list.append是原地操作。这就是它的含义:
有两种类型:可变和不可变。
可变类型在内存中占据相同的位置,即使您更改了它。例如,list和dict是可变类型。这意味着如果您创建了一个名为“myList”的list并以某些方式更改它,则它仍将位于内存中的相同位置。因此,假设您创建了一个在内存位置0x9000的list。然后,执行myList.append(0)不会更改myList在内存中的位置。即使您执行了myList[0] = 'a',位置也不会改变-它仍将位于0x9000。
当您尝试以任何方式更改不可变类型时,它将“移动”到不同的内存位置。str和tuple是不可变的。这就是为什么您会收到以下错误的原因:
>>> 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]
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
希望这能帮到您。