我每次运行这个程序,我得到这个错误:
ValueError: list.remove(x): x not in list
我试图降低时,它是由一个螺栓打出单外国人的健康。 该单个外来还应如果它的健康是破坏<= 0
。 同样,螺栓也将被销毁。 这里是我的代码:
def manage_collide(bolts, aliens):
# Check if a bolt collides with any alien(s)
for b in bolts:
for a in aliens:
if b['rect'].colliderect(a['rect']):
for a in aliens:
a['health'] -= 1
bolts.remove(b)
if a['health'] == 0:
aliens.remove(a)
# Return bolts, aliens dictionaries
return bolts, aliens
该ValueError
情况就行了aliens.remove(a)
。 只是为了澄清,无论是aliens
和bolts
是字典的名单。
我究竟做错了什么?
你不应该从你遍历一个列表中删除项目。 创建一个副本,而不是:
for a in aliens[:]:
和
for b in bolts[:]:
修改列表,同时遍历它,影响环路:
>>> lst = [1, 2, 3]
>>> for i in lst:
... print i
... lst.remove(i)
...
1
3
>>> lst
[2]
从你遍历两次列表中删除项目会使事情更加复杂的是,导致一个ValueError:
>>> lst = [1, 2, 3]
>>> for i in lst:
... for a in lst:
... print i, a, lst
... lst.remove(i)
...
1 1 [1, 2, 3]
1 3 [2, 3]
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
ValueError: list.remove(x): x not in list
当你创建你的循环的每一层都修改名单的副本,你避免这个问题:
>>> lst = [1, 2, 3]
>>> for i in lst[:]:
... for i in lst[:]:
... print i, lst
... lst.remove(i)
...
1 [1, 2, 3]
2 [2, 3]
3 [3]
当你有一个碰撞,你只需要删除b
一旦螺栓,而不是在你伤害外星人循环。 以后单独清理出外星人:
def manage_collide(bolts, aliens):
for b in bolts[:]:
for a in aliens:
if b['rect'].colliderect(a['rect']) and a['health'] > 0:
bolts.remove(b)
for a in aliens:
a['health'] -= 1
for a in aliens[:]:
if a['health'] <= 0:
aliens.remove(a)
return bolts, aliens
有一个在你的代码中的错误导致此。 您的代码,简化的,是这样的:
for b in bolts:
for a in aliens:
for a in aliens:
bolts.remove(b)
这是造成你遍历aliens
多次在每个条目b
。 如果B在在第一循环中去除aliens
的话,当上循环,第二次,你会得到有错误。
有几件事情来解决。 首先,在内部循环换过来aliens
使用其他的东西比a
,因此:
for b in bolts:
for a in aliens:
for c in aliens:
if hit:
bolts.remove(b)
其次,只删除b
从bolts
一次。 所以:
for b in bolts:
for a in aliens:
should_remove = False
for c in aliens:
if hit:
should_remove = True
if should_remove:
bolts.remove(b)
还有其他问题与此代码为好,但是我认为,这是导致你的主要问题。 马亭的帖子也可能会有帮助。
给螺栓“健康”为好,初始化为1。然后,你可以做一个嵌套循环计算所有的伤害,和两个独立的嵌套的“循环”中删除一切的“死”。 除此之外,不这样做完全是这样,因为你还是不想修改,你遍历列表。 制作副本还是太复杂了。 你真正想要做的是直接建造的只有还“活着”的东西一个新的列表 ,你可以做到这一点描述性与列表理解(或如图所示,与filter
)。
# for example
class Alien:
# ... other stuff
def damage(self): self.hp -= 1
def alive(self): return self.hp > 0
# similarly for Bolt
def collide(an_alien, a_bolt):
# etc.
def handle_collisions(aliens, bolts):
for a in aliens:
for b in bolts:
if collide(a, b):
a.damage()
b.damage()
return list(filter(Alien.alive, aliens)), list(filter(Bolt.alive, bolts))