递归创建带间距过滤的坐标列表时元素莫名篡改问题
问题根源:对象引用复用导致列表元素被篡改
你遇到的这个问题,核心原因是你一直在复用同一个positions对象实例。Python里列表存储的是对象的引用,而非对象的副本。当你在循环里反复给positions.x、positions.y、positions.z赋值,再把它添加到self.pickposes列表时,列表里所有元素其实都指向同一个positions对象。后续循环修改这个对象的属性时,之前添加到列表里的"旧元素"自然也会跟着变化——因为它们本质上就是同一个东西。
看你代码里的关键问题点:
# 始终修改同一个positions对象的属性 positions.x = self.poses[i].position.x positions.y = self.poses[i].position.y positions.z = self.poses[i].position.z # 把同一个对象的引用重复添加到列表 self.pickposes.append(positions)
比如第一次添加时,列表存的是positions的引用;第二次循环你修改了positions的属性,列表里第一个元素的引用指向的还是这个对象,所以它的值会被覆盖成新的属性值,这就是你看到"旧坐标被篡改"的原因。
解决方案:每次添加时创建新的positions实例
你需要在每次准备添加新坐标时,创建一个全新的positions对象(而非复用旧的),这样列表里的每个元素都是独立的实例,后续修改不会影响之前的元素。
修改后的核心代码示例:
# 不要复用旧的positions,每次新建一个实例(注意替换成你实际使用的类名) new_positions = Position() new_positions.x = self.poses[i].position.x new_positions.y = self.poses[i].position.y new_positions.z = self.poses[i].position.z if len(self.pickposes) == 0: print('posistion voor real cente:', new_positions) print('list empty') self.pickposes.append(new_positions) print(self.pickposes) else: tmp = 0 loop_length = len(self.pickposes) for j in range(loop_length): # 后续逻辑都使用新创建的new_positions if (abs(new_positions.y - self.pickposes[j].y) > 0.09): print('y = ', new_positions.y) print(j) print("compared to : ", self.pickposes[j].y) print('abs pose diff = ', abs(new_positions.y - self.pickposes[j].y)) tmp += 1 print('tmp in for loop =', tmp) print('tmp outside for =',tmp) print('loop length', loop_length) if loop_length <= self.index: if tmp == loop_length: print('posistion to add to l', new_positions) print("list of poses:", self.pickposes) self.pickposes.append(new_positions) print("list of poses:", self.pickposes)
额外优化建议
- 可以把坐标间距检查的逻辑抽成单独函数,比如
is_valid_y_spacing(new_y, existing_poses),让代码更清晰,也方便后续调试和维护。 - 虽然你当前用固定阈值0.09处理浮点数比较已经满足需求,但如果后续遇到精度问题,也可以考虑用
math.isclose结合自定义容差来做更严谨的浮点数判断。
内容的提问来源于stack exchange,提问作者Thomas Hordijk
相关产品推荐
相关产品推荐

