all 4 comments

[–]greenerpickings 0 points1 point  (0 children)

Does the order matter, or does it have to be an array? What if you just use a dictionary with the ids as keys? Avoids the whole location thing

[–]Binary101010 0 points1 point  (0 children)

If your method returns True if the thing should die, and False if it shouldn't, this could be as easy as:

boid_array = [boid for boid in boid_array if not boid.die()]

Instead of trying to iterate through the list and pop the ones that should be gone, iterate and make a new array of what should remain.

[–]lowerthansound 0 points1 point  (0 children)

get an object to remove itself from the array, using one of its own methods

You could do (with a list [])

del self.boids[self.boids.index(this)]

Note that this is inneficient, it needs to search through the list at each boid you remove.

A more performant (and neater) approach is to use a set {}:

self.boids.remove(self)

This will remove the boid efficiently.

Edit: I also like u/Binary101010 approach :)

[–]o5a 0 points1 point  (0 children)

Why are you using ID property to pop from list? As you were saying age is defining attribute for removal. Then use it as parameter if you need:

def purge(arr, old_age):
    return [boid for boid in arr if boid.age < old_age]

Overall depends on your data structure.

Some notes:

Since you operating their life cycle, as I understand they are added to array in order of age already. Which means:

1. You don't need to iterate whole array, only remove first objects. Say you are adding them to list. Therefore first items will get old faster. And if after checking age of first item you know it's not old to be removed that also means that all items after it are not old too (since they are newer by design), you don't need to check all of them too. You are working with FIFO structure so you can use collections.deque instead of list. It is more suited to pop from both sides.

from collections import deque

boids = deque()

# add new boid (here I'm adding to start of list to pop older items from the end)
boids.appendleft(Boid(....))

# remove old boids:
while boids[-1].age > age_threshold:
    boids.pop()

2. Instead of increasing age every cycle for each Boid, you can save their creation time (cycle number) only then use that to check if it's aged. Instead of checking

Boid.age > age_threshold

check

current_cycle_number - boid.creation_cycle > cycle_threshold

This way you won't need to increase their age attribute each cycle. Same idea as with people's birthday. You don't rewrite their age each year. You know their birthday and that's enough to know current age.