Reputation: 996
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
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
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