Nested for loop not looping on the first set, Python
zip(y_start, y_end) returns an iterator.  After the first series of Xs, y_inds is exhausted and yields no more values for the subsequent values of X.
Make it y_inds a list, so it can be reused on subsequence X rows:
*y_inds, = zip(y_start, y_end)

You could also let numpy do the iterating for you to produce a matrix of square coordinates:
coords  = np.repeat(x_start,y_start.size)[:,None], \
          np.repeat(x_end,  y_start.size)[:,None], \
          np.tile(y_start,x_start.size)[:,None],   \
          np.tile(y_end,  x_start.size)[:,None]
squares = np.concatenate(coords,axis=1)
print(squares)
[[  0  30   0  30]
 [  0  30  20  55]
 [  0  30  45  80]
 [  0  30  70 100]
 [ 20  55   0  30]
 [ 20  55  20  55]
 [ 20  55  45  80]
 [ 20  55  70 100]
 [ 45  80   0  30]
 [ 45  80  20  55]
 [ 45  80  45  80]
 [ 45  80  70 100]
 [ 70 100   0  30]
 [ 70 100  20  55]
 [ 70 100  45  80]
 [ 70 100  70 100]]


I have written this code in python. In the end I would like to use this to get the indices to cut up a 100x100 matrix into squares that overlap by 10. However, at the bottom there is a nested loop and the y values print how I think they should but not the x-values, the x-values never change... Can anyone help? Thanks
x_split = np.linspace(0, 100, 4 + 1, dtype=int)
x_start = x_split[:-1] - 5
x_start[0] = 0
x_end = x_split[1:] + 5
x_end[-1] = 100

y_split = np.linspace(0, 100, 4 + 1, dtype=int)
y_start = y_split[:-1] - 5
y_start[0] = 0
y_end = y_split[1:] + 5
y_end[-1] = 100

x_inds = zip(x_start, x_end)
y_inds = zip(y_start, y_end)

i = 0
for start_x, end_x in x_inds:
    for start_y, end_y in y_inds:
        i += 1
        print(f"i = {i}")
        print(f"x = {start_x} {end_x}")
        print(f"y = {start_y} {end_y}")
        print("")

Current output:
i = 1
x = 0 30
y = 0 30

i = 2
x = 0 30
y = 20 55

i = 3
x = 0 30
y = 45 80

i = 4
x = 0 30
y = 70 100

And then stops. I want to to continue...
i = 5
x = 20 55
y = 0 30

i = 6
x = 20 55
y = 20 55

...

