假设我有一个包含运动对象实例的字典。每个运动对象都有一个位置,速度等。在程序的每个时间步更新中,我想检查两个活动对象(不是同一个对象,请注意)是否占据参考框架中的相同位置。如果他们这样做,这将模拟一个碰撞,所涉及的两个对象将被销毁,他们的实例将从活动对象字典中删除。
dict actives{ 'missile' : object_c(x1, y1, z1),
'target' : object_c(x2, y2, z2),
'clutter' : object_c(x3, y3, z3),
... }
...
for key1 in self.actives.keys():
for key2 in self.actives.keys():
if not key1 == key2:
# Get Inertial Positions and Distance
Pos21 = self.actives[key2].Pos - self.actives[key1].Pos
distance = math.sqrt(sum(Pos21**2))
# If Distance <= Critical Distance
if distance <= 1.0e0
# Remove key1 and key2 from Actives
# -- This is where I need help --
我不能使用del
:密钥(和对象)将从活动中删除,但for
循环'条件无法识别这个并且会遇到KeyError。在访问循环条件的键时,如何从活动中删除这些对象?
答案 0 :(得分:1)
简单的解决方案,将要删除的键添加到列表中,然后在循环遍历所有元素后将其删除:
dict actives{ 'missile' : object_c(x1, y1, z1),
'target' : object_c(x2, y2, z2),
'clutter' : object_c(x3, y3, z3),
... }
to_be_removed = list()
...
for key1 in self.actives.keys():
for key2 in self.actives.keys():
if not key1 == key2:
# Get Inertial Positions and Distance
Pos21 = self.actives[key2].Pos - self.actives[key1].Pos
distance = math.sqrt(sum(Pos21**2))
# If Distance <= Critical Distance
if distance <= 1.0e0
# Remove key1 and key2 from Actives
# -- This is where I need help --
to_be_removed.append(key1)
to_be_removed.append(key2)
for remove_me in to_be_removed:
self.actives.pop(remove_me, None)
答案 1 :(得分:1)
在您循环播放时,您可以仔细检查密钥是否仍然存在:
for key1 in self.actives.keys():
if key1 not in self.actives:
continue
for key2 in self.actives.keys():
if key2 not in self.actives:
continue
# okay, both keys are still here. go do stuff
if not key1 == key2:
答案 2 :(得分:1)
我认为Maximilian Peters有正确的基本想法,但要删除的项目应保存在set
而不是list
中,以避免多次出现活动密钥问题。为了进一步加快碰撞检测过程,我改变了比较循环以使用react-native doc for Dimensions API生成器函数,以便只测试唯一的对象对。
我还必须添加相当数量的脚手架,以便可以在上下文中测试代码,就像你可能已经运行...
from itertools import combinations
import math
CRITICAL_DIST = 2.0e0
class ObjectC(object):
def __init__(self, x, y, z):
self.posn = x, y, z
def __repr__(self):
return '{}({}, {}, {})'.format(self.__class__.__name__, *self.posn)
class Game(object):
def remove_collisons(self):
to_remove = set()
for key1, key2 in combinations(self.actives, 2):
# Calculate distance.
deltas = (
(self.actives[key2].posn[0] - self.actives[key1].posn[0])**2,
(self.actives[key2].posn[1] - self.actives[key1].posn[1])**2,
(self.actives[key2].posn[2] - self.actives[key1].posn[2])**2)
distance = math.sqrt(sum(deltas))
# Check for collision.
if distance <= CRITICAL_DIST:
to_remove |= {key1, key2} # both objects should be removed
if to_remove:
print('removing: {!r}'.format(list(to_remove)))
self.actives = {
k: v for k, v in self.actives.items() if k not in to_remove}
x1, y1, z1 = 0, 1, 2
x2, y2, z2 = 1, 2, 3
x3, y3, z3 = 2, 3, 1
actives = {'missile' : ObjectC(x1, y1, z1),
'target' : ObjectC(x2, y2, z2),
'clutter' : ObjectC(x3, y3, z3),
} # ...
game = Game()
game.actives = actives
print('before: {}'.format(game.actives))
game.remove_collisons()
print('after: {}'.format(game.actives))
输出:
before: {'clutter': ObjectC(2, 3, 1), 'target': ObjectC(1, 2, 3), 'missile': ObjectC(0, 1, 2)}
removing: ['target', 'missile']
after: {'clutter': ObjectC(2, 3, 1)}