API: how to iterate over a planes vertices row-by-row, column-by-column
Not elegant, and it has no verification that the object is a regular plane (only 4 outer edges) but the below has been tested a bit and provides a single sequence of vertices as described in your question. Maybe someone else can follow up with a cleaner solution.

import bpy
import bmesh

my_data = []
my_corners = []
my_seq_cols = []
my_seq_verts = []
edg_cnt = 0
my_mode = 'OBJECT'
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.mode_set(mode='EDIT')
obj = bpy.context.edit_object
me = obj.data
bm = bmesh.from_edit_mesh(me)
bm.verts.ensure_lookup_table()
bm.edges.ensure_lookup_table()


def set_mode(my_mode):
    bpy.ops.object.mode_set(mode=my_mode)


def set_data(my_data, edg_cnt):
    for vert in bm.verts:
        my_data.append([vert.co[0], vert.co[1], vert.index, edg_cnt])
    return my_data


def find_corners(my_data, my_corners):
    for edg in range(len(bm.edges)):
        for vert in range(len(bm.edges[edg].verts)):
            for i in my_data:
                if i[2] == bm.edges[edg].verts[vert].index:
                    i[3] += 1
    for i in my_data:
        if i[3] == 2:
            my_corners.append(i)
    return my_corners


def find_edg_from_verts(v1, v2):
    for edg in bm.edges:
        if (edg.verts[0] == v1 and edg.verts[1] == v2) or (edg.verts[1] == v1 and edg.verts[0] == v2):
            my_edg = edg
    return (my_edg)


def find_start_col(corners):
    for edg in bm.edges:
        if (edg.verts[1].index == corners[0][2]):
            col_ind = edg
    return (col_ind)


def find_start_row(corners):
    for edg in bm.edges:
        if (edg.verts[0].index == corners[0][2]):
            row_ind = edg
    return (row_ind)


def get_row_verts(my_row_start):
    bpy.ops.mesh.select_all(action='DESELECT')
    my_row_start.select = True
    bpy.ops.mesh.loop_multi_select(ring=False)


def seq_sel_verts(start_vert):
    found = False
    fwd = True
    sel_verts = [v for v in bm.verts if v.select]
    for l in start_vert.link_loops:  # try to find next vert of loop
        if l.link_loop_next.vert in sel_verts:
            next_vert = l.link_loop_next.vert
            found = True
    if not found:
        for l in start_vert.link_loops:  # last row requires direction change
            if l.link_loop_prev.vert in sel_verts:
                next_vert = l.link_loop_prev.vert
                fwd = False
    cnt = len(sel_verts)
    if fwd:
        while cnt &gt; 0:
            for l in start_vert.link_loops:
                if (l.link_loop_next.vert in sel_verts) and (l.link_loop_next.vert not in my_seq_verts):
                    next_vert = l.link_loop_next.vert
            for v in sel_verts:
                if v == start_vert:
                    my_seq_verts.append(v)
                    v.select = False
            start_vert = next_vert
            cnt -= 1
    else:
        while cnt &gt; 0:
            for l in start_vert.link_loops:
                if (l.link_loop_prev.vert in sel_verts) and (l.link_loop_prev.vert not in my_seq_verts):
                    next_vert = l.link_loop_prev.vert
            for v in sel_verts:
                if v == start_vert:
                    my_seq_verts.append(v)
                    v.select = False
            start_vert = next_vert
            cnt -= 1


def seq_sel_cols(start_vert):
    next_vert = start_vert.link_loops[0].link_loop_prev.vert
    sel_verts = [v for v in bm.verts if v.select]
    cnt = len(sel_verts)
    while cnt &gt; 0:
        for l in start_vert.link_loops:
            if l.link_loop_prev.vert in sel_verts:
                next_vert = l.link_loop_prev.vert
        for v in sel_verts:
            if v == start_vert:
                my_seq_cols.append(v)
                v.select = False
        start_vert = next_vert
        cnt -= 1


def output(row_len):
    col_len = len(my_seq_cols)
    print("Vertex sequence")
    cnt = 0
    for i in range(col_len):
        print("&lt;row:", i, end="&gt; ")
        for j in range(row_len):
            print(my_seq_verts[cnt].index, end=", ")
            cnt += 1
        print()
    print("Total vertices:", len(my_seq_verts))


def main():
    set_mode('EDIT')
    set_data(my_data, edg_cnt)
    find_corners(my_data, my_corners)

    my_corners.sort()  # organize list so lowest (x,y) is 1st
    start_col = find_start_col(my_corners)

    # sequence leftmost(-x) column bottom to top(-y...+y)
    get_row_verts(start_col)
    my_start_vert = start_col.verts[1]
    seq_sel_cols(my_start_vert)

    # sequence rows from left to right (-x...+x)
    for v in my_seq_cols:
        found = False
        my_start_vert = v
        for l in my_start_vert.link_loops:
            if l.link_loop_next.vert not in my_seq_cols:
                found = True
                next_v = l.link_loop_next.vert
                start_row = find_edg_from_verts(my_start_vert, next_v)
                get_row_verts(start_row)
                seq_sel_verts(my_start_vert)
        if not found:
            for l in my_start_vert.link_loops:
                if l.link_loop_prev.vert not in my_seq_cols:
                    found = True
                    next_v = l.link_loop_prev.vert
                    start_row = find_edg_from_verts(my_start_vert, next_v)
                    get_row_verts(start_row)
                    row_len = len([v for v in bm.verts if v.select])  # added for formatting output
                    seq_sel_verts(my_start_vert)
    output(row_len)
    bm.free()
    set_mode('OBJECT')


main()