Reputation: 969
I have a 2d array with a different species in each one. I pick a random element on the array and I want to count up how many of each species are in the eight squares immediately adjacent to that element.
But I want the array to wrap at the edges, so if I pick an element on the top row, the bottom row will be counted as "adjacent". How can I do this while iterating through j in range (x-1,x+1)
and the same for j and y?
Also, is there a more elegant way of omitting the element I originally picked while looking through the adjacent squares than the if (j!=x or k!=y
line?
numspec = [0] * len(allspec)
for i in range (0,len(allspec)):
#count up how many of species i there is in the immediate area
for j in range(x-1,x+1):
for k in range(y-1,y+1):
if (j!=x or k!=y):
numspec[hab[i][j]] = numspec[hab[i][j]]+1
Upvotes: 0
Views: 7055
Reputation: 5537
As for wrapping, I would recomend using relative indexing from -1 to +1 and then computing real index using modulo operator (%
).
As for making sure you don't count the original element (x, y), you are doing just fine (I would probably use reversed contidion and continue, but it doesn't matter).
I don't quite understand your usage of i, j, k
indexes, so I'll just assume that i
is index of the species, j, k
are indexes into the 2d map called hab
which I changed to x_rel
, y_rel
and x_idx
and y_idx
to make it more readable. If I'm mistaken, change the code or let me know.
I also took the liberty of doing some minor fixes:
N
constant representing number of speciesrange
to xrange
(xrange is faster, uses less memory, etc)X = X + 1
for increasing value, I used +=
increment operator like this: X += 1
Here is resulting code:
N = len(allspec)
numspec = [0] * N
for i in xrange(N):
for x_rel in xrange(-1, +1):
for y_rel in xrange(-1, +1):
x_idx = (x + xrel) % N
y_idx = (y + yrel) % N
if x_idx != x or y_idx != y:
numspec[hab[x_idx][y_idx]] += 1
Upvotes: 1
Reputation: 16242
You could construct a list of the adjacent elements and go from there. For example if your 2d list is called my_array
and you wanted to examine the blocks immediately surrounding my_array[x][y]
then you can do something like this:
xmax = len(my_array)
ymax = len(my_array[0]) #assuming it's a square...
x_vals = [i%xmax for i in [x-1,x,x+1]]
y_vals = [blah]
surrounding_blocks = [
my_array[x_vals[0]][y_vals[0]],
my_array[x_vals[0]][y_vals[1]],
my_array[x_vals[0]][y_vals[2]],
my_array[x_vals[2]][y_vals[0]],
my_array[x_vals[2]][y_vals[1]],
my_array[x_vals[2]][y_vals[2]],
my_array[x_vals[1]][y_vals[0]],
my_array[x_vals[1]][y_vals[2]],
]
Upvotes: 0