用字典键值对来存储数据 {(0,0): 1, (0,1):2,....}。 用生成器来生成坐标和数据。

假设是5×5的列表,那么第一次转换方向的位置在(0,5)然后向下,第二次转换方向的位置在(5,4),然后向右,第三次转换方向位置在(4,-1),然后向上碰到第一次填数据的位置(0,0)进行判断,此时(0,0)已在字典中,所以不填数据,并换继续循环。

由此可见,只需要提前预设好三个关键的转折点即可。

# 产生新节点
def newnode():
    while True:
        yield (0, 1)  # 向右走:lis[不变][+1]
        yield (1, 0)  # 向下走:lis[+1][不变]
        yield (0, -1)  # 向左走:lis[不变][-1]
        yield (-1, 0)  # 向上走:lis[-1][不变]

# 产生新数据
def newnum():
    num = 1
    while True:
        yield num  # 返回num
        num += 1

# 得到新的节点
def getnext():
    node = (0, 0)  # 初始节点
    objp = newnode()  # 创建 新节点生成器对象
    p = next(objp)  # 调用产生 新节点坐标 应该加的数据
    while True:
        yield node  # 返回节点坐标
        # 旧节点坐标加上p即新的坐标
        # 例:第二个坐标(0,1)=(0(旧)+0,0(旧)+1)
        new_node = (node[0] + p[0], node[1] + p[1])
        if new_node in dic:  # 如果新的节点在字典中
            p = next(objp)  # 则重新产生新节点即转换方向
            new_node = (node[0] + p[0], node[1] + p[1])
            if new_node in dic:  # 如果存在则说明已经结束
                break
        node = new_node  # 新节点数据给 node 



r = int(input())
c = r

dic = {}
# 关键转折点,值可以随便填,主要是将转折点的坐标存在字典中。
dic[(0, c)] = 'x'  
dic[(r, c - 1)] = 'x'
dic[(r - 1, -1)] = 'x'

num = newnum()  # 创建 产生新数据 对象
for node in getnext(): 
    dic[node] = next(num)  # 将节点与对应的数据存入字典

# 遍历
for x in range(r):
    for y in range(c):
        print(dic[(x, y)], end=' ')  # 按键从字典中取值
    print()