1. ホーム
  2. python

[解決済み】Python throws ValueError: list.remove(x): xがリストにない。

2022-02-08 22:47:28

質問

このプログラムを実行するたびに、このエラーが発生します。

ValueError: list.remove(x): x not in list

私は、1体のエイリアンにボルトが当たるたびに、そのエイリアンのヘルスを下げようとしています。また、そのエイリアンはヘルスが <= 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) . はっきりさせるために、両方の aliensbolts は辞書のリストである。

何が間違っているのでしょうか?

どうすればいいですか?

ループしているリストから項目を削除してはいけません。代わりにコピーを作成してください。

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]

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