You can easily execute it by replacing the calculations with the actual values:
In the first call, you index:
bships[cb][a-1] == bships[4-1][1-1] == bships[3][0]
Count from 0 that the last line, ['0','0','0','0'] , the first element, '0' .
The second call is evaluated as:
bships[cb][a-1] == bships[4-2][1-1] == bships[2][0]
therefore, the first cell of the second row, ['p','p','0','s'] is 'p' .
Note that in Python you can use negative indices without first evaluating len() ; remove c from your function and everything will work the same:
>>> battleships = [['0','p','0','s'], ... ['0','p','0','s'], ... ['p','p','0','s'], ... ['0','0','0','0']] >>> def fun(a,b,bships): ... return bships[-b][a-1] ... >>> print(fun(1,1,battleships)) 0 >>> print(fun(1,2,battleships)) p
This is because Python processes negative indices from the end; internally, it will use the length of the sequence (which is stored in the sequence) to calculate the same thing, but faster.