Python 抛出 ValueError: list.remove(x): x not in list
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14126726/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python throws ValueError: list.remove(x): x not in list
提问by Remolten
Every time I run this program, I get this error:
每次我运行这个程序时,我都会收到这个错误:
ValueError: list.remove(x): x not in list
I am trying to lower the health of a single alien whenever it is hit by a bolt. That single alien should also be destroyed if its health is <= 0. Similarly, the bolt would also be destroyed. Here is my code:
每当一个外星人被螺栓击中时,我都试图降低它的健康。如果单个外星人的健康状况为<= 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
The ValueErrorhappens on the line aliens.remove(a). Just to clarify, both the aliensand boltsare lists of dictionaries.
在ValueError上线情况aliens.remove(a)。只是为了澄清,aliens和bolts都是字典列表。
What am I doing wrong?
我究竟做错了什么?
采纳答案by Martijn Pieters
You should not remove items from a list you are looping over. Create a copy instead:
你不应该从你正在循环的列表中删除项目。改为创建副本:
for a in aliens[:]:
and
和
for b in bolts[:]:
Modifying a list while looping over it, affects the loop:
在循环时修改列表会影响循环:
>>> lst = [1, 2, 3]
>>> for i in lst:
... print i
... lst.remove(i)
...
1
3
>>> lst
[2]
Removing items from a list you are looping over twice makes things a little more complicated still, resulting in a ValueError:
从您循环两次的列表中删除项目会使事情变得更加复杂,从而导致 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
When creating a copy of the lists you are modifying at eachlevel of your loops, you avoid the problem:
在创建您在循环的每个级别修改的列表的副本时,您可以避免这个问题:
>>> 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]
When you have a collision, you only need to remove the bbolt once, not in the loop where you hurt the aliens. Clean out the aliens separately later:
当你发生碰撞时,你只需要移除一次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
回答by dave mankoff
There is a bug in your code that is causing this. Your code, simplified, looks like:
您的代码中存在导致此问题的错误。您的代码经过简化,如下所示:
for b in bolts:
for a in aliens:
for a in aliens:
bolts.remove(b)
That is causing you to loop over aliensmultiple times for every entry in b. If the b is removed on the first loop over aliensthen, when it loops over it a second time, you will get there error.
这是造成你遍历aliens多次在每个条目b。如果 b 在第一次循环中被删除,aliens那么当它第二次循环时,你会得到那里的错误。
A few things to fix. First, change in the inner loop over aliensto use something other than a, so:
一些事情要解决。首先,更改内部循环aliens以使用除 之外的其他内容a,因此:
for b in bolts:
for a in aliens:
for c in aliens:
if hit:
bolts.remove(b)
Second, only remove bfrom boltsonce. so:
其次,只能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)
There are other issues with this code as well, I think, but that is the cause your main problem. Martijn's post may also help.
我认为此代码还有其他问题,但这是导致您的主要问题的原因。Martijn 的帖子也可能有所帮助。
回答by Karl Knechtel
Give the bolts a "health" as well, initialized to 1. Then you can do one nested loop to calculate all the damage, and two separate unnested "loops" to remove everything that's "dead". Except, don't do it quite like that, because you still don't want to modify the list that you're looping over. Making a copy is still too complicated. What you really want to do is directly build a new list of only the still "alive" things, and you can do that descriptively with list comprehensions (or as shown here, with filter).
也给螺栓一个“健康”,初始化为 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))
回答by Alaa Hassabalah
I think if you replaced for loop with while loop - only in loop in which you remove from list - will solve it
我认为如果你用 while 循环替换 for 循环 - 只有在你从列表中删除的循环中 - 将解决它
Like this
像这样
lis = [1,2,3,4,5,6]
i=0
while i in range(len(lis)) :
lis. remove(lis[i])
回答by Alaa Hassabalah
you can not use list.remove you should use del list[x]
你不能使用 list.remove 你应该使用 del list[x]
Because when you use remove you must name the deleted item by name not by index, so when the code is operated this error will appear (value error: x is not in list) But when we use del it is ok because we delete item by its index. Whatever the item's name is, using del, the code will operate correctly I hope i cleared the problem and solved it
因为当你使用remove时你必须按名称而不是索引来命名被删除的项目,所以当代码操作时会出现这个错误(值错误:x不在列表中)但是当我们使用del时就可以了,因为我们删除项目它的索引。无论项目的名称是什么,使用del,代码都会正确运行我希望我清除了问题并解决了它
To know what i mean exactly please try this code Then try it by repacing del with remove and you will know what i mean. The code is below:
要确切地知道我的意思,请尝试此代码然后通过用删除重新调整 del 来尝试它,您就会知道我的意思。代码如下:
aliens = [[4,3,2,1],[4,3,2,1],[4,3,2,1]]
print(aliens)
bolts = [b for b in range(1,30)]
for b in bolts:
del aliens[0][0]
print(aliens)
if len(aliens[0]) == 0:
del aliens[0]
if len(aliens) == 0
print("you win")
break

