Question

So I was working on my top-down rpg project and I made some changes in the movement of npcs. More specifically before I move any npc I first check whether its next position is taken basically.

So obviously in order to achieve that, I need for every npc to check the current positions of all other npcs.

So my question is which is the best pythonic way to iterate through a list of objects and in every iteration access the whole list but the list's element with the current index.

A way I thought of was:

for index,element in enumerate(my_list):
    print my_list[:index] + my_list[index + 1:]

But I would like to know any other possible ways :) Cheers and although I checked thoroughly I couldn't find a similar question, so feel free to inform me for any other possible duplicates!

Alex

Was it helpful?

Solution

Actually, your approach is pretty readable, but inefficient for large lists(it builds list again everytime).

I'd probably use a simple for loop:

for i, j in enumerate(my_list):
    for elem in (v for k, v in enumerate(my_list) if k != i):
        print elem, 

Edit: For performance, you can use itertools.ifilter, which doesn't build a list. On Python 3, built-in filter behaves the same.

OTHER TIPS

If you're looking for both memory efficient and fast solution then you can use itertools.islice with itertools.chain here. This is going to be faster than @utdemir's solution because in filtering step no Python for-loop is involved:

from itertools import islice, chain

def islice_ashwch(my_list):
    for i, j in enumerate(my_list):
        for elem in chain(islice(my_list, i), islice(my_list, i+1, None)):
            pass

def gen_utd(my_list):
    #https://stackoverflow.com/a/22944093/846892
    for i, j in enumerate(my_list):
        for elem in (v for k, v in enumerate(my_list) if k != i):
            pass

Timing comparison:

In [6]: lst = range(100)

In [7]: %timeit gen_utd(lst)
1000 loops, best of 3: 680 µs per loop

In [8]: %timeit islice_ashwch(lst)
1000 loops, best of 3: 204 µs per loop

In [9]: lst = range(1000)

In [10]: %timeit gen_utd(lst)
10 loops, best of 3: 63.3 ms per loop

In [11]: %timeit islice_ashwch(lst)
100 loops, best of 3: 16.2 ms per loop
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top