iterate through all selected objects, but do a different operation to each one
Fortunately, your code can be made a lot simpler. In Python it is rarely needed to iterate over a collection and keep track of an index yourself, thanks to the built-in enumerate() function. Here is how I would do this:

Update: I've adjusted the code below to take the row length into account, and stack the objects in a grid.

import bpy

offset_y = 2.5
offset_z = 3
row_length = 5

for nr, obj in enumerate(bpy.context.selected_objects):
    row = nr % row_length
    col = nr // row_length
    obj.location = (0, row * offset_y, col * offset_z)


I have also renamed rowLength to row_length, as in Python usually local variables are all lower caps with underscores.

The trick is to first compute the row and column number given the object number, and then compute the Y and Z coordinates from the row and column.