Alex Koukoulas
Alex Koukoulas

Reputation: 996

During an iteration print the whole list but the current index

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

Upvotes: 0

Views: 82

Answers (2)

Ashwini Chaudhary
Ashwini Chaudhary

Reputation: 250941

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

Upvotes: 1

utdemir
utdemir

Reputation: 27216

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.

Upvotes: 1

Related Questions