# \[SOLVED\] Py.processing bullet and enemy collision

**URL:** <https://discourse.processing.org/t/solved-py-processing-bullet-and-enemy-collision/8327>\
**Category:** Processing.py\
**Created:** [February 12, 2019, 5:12pm UTC](https://discourse.processing.org/t/solved-py-processing-bullet-and-enemy-collision/8327 "2019-02-12T17:12:42Z")\
**Posts on this page:** 1\
**Showing post:** 4

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [February 13, 2019, 9:04am UTC](https://discourse.processing.org/t/solved-py-processing-bullet-and-enemy-collision/8327/4 "2019-02-13T09:04:03Z")

</div>

@solub, your solution is buggy! 🐛

When we delete an item from a list, all elements w/ a higher index than the deleted item got their indices subtracted by 1! 🧐

They’re left-shifted, and therefore, the next iteration skips an item; which now got the same index as the just deleted item. ⬅

You can see that bug in this sample loop below: 👁 :

```auto
nums = list(range(10)) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
for n in nums:
    print n
    nums.remove(n)
print nums # [1, 3, 5, 7, 9] 

```

The code above was supposed to remove all items from the list. But accomplished only half of it! 🤪

There are some techniques to pull that out though. 💡

In Java, my favorite approach is to simply traverse the list backwards instead. ☕

Python got **reversed()**, which returns a backwards iterator for a sequence. 🐍

```auto
nums = list(range(10)) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
for n in reversed(nums):
    print n
    nums.remove(n)
print nums # [] 

```

Now it’s finally worked! All items got backwards removed w/o any errors! 🥳

However, **remove()** ( and also **index()** ) is a slow method, given it’s gotta search the whole list for the target item. 🐌

A better approach is to use `del`, since it removes an item by its index. 🗂

For that, we’re gonna need to use **enumerate()** and also turn it into a sequence before calling **reversed()**: 🔙

```auto
nums = list(range(10)) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
for i, n in reversed(tuple(enumerate(nums))):
    print i, n
    del nums[i]
print nums # [] 

```

Here’s @warsoldier011’s excerpt adapted to use a backwards loop w/ `del`: 👼

```python
for i, e in reversed(tuple(enumerate(enemies))):
    e.display()
    e.goToTarget(myPlayer.xpos, myPlayer.ypos)

    # for j, l in reversed(tuple(enumerate(lasers))): # no need w/ break
    for j, l in enumerate(lasers):
        if l.collision(e.xpos, e.ypos, e.r):
            del lasers[j]
            del enemies[i]
            break

        l.display()

```

As a bonus, here’s a more advanced performant example, which replaces the item being removed w/ its list’s tail element; so there’s no index left-shifting at all: 🤑

```python
for i in range(len(enemies) - 1, -1, -1):
    e = enemies[i]

    e.display()
    e.goToTarget(myPlayer.xpos, myPlayer.ypos)

    # for j in range(len(lasers) - 1, -1, -1): # no need to be reversed w/ break
    for j in range(len(lasers)):
        l = lasers[j]

        if l.collision(e.xpos, e.ypos, e.r):
            tail = lasers.pop()
            if tail is not l: lasers[j] = tail

            tail = enemies.pop()
            if tail is not e: enemies[i] = tail

            break

        l.display()

```

---

_[View the full topic](https://discourse.processing.org/t/solved-py-processing-bullet-and-enemy-collision/8327)._
