效果图:
注意哦,右边多出来的一点不是程序有问题,是打印的时候我用的\t,但100,三个字符顶格的时候给顶出去的,我太懒了,不想再调输出格式了,就这么凑合看吧
实现代码:
sum = int(input("Please input a num:"))end = [[0 for i in range(sum)] for i in range(sum)]#初始化二维数组(列表)num = list(range(1,sum*sum+1))XH = sum / 2#用于记录循环次数CS = 0#用于记录当前层数(从0开始)for i in range(int(XH)): b = 0 #用于卡住嵌套循环,让其每次循环不是全部n*n遍历而是1*1走直角 c = 0 #用于记录跳跃,防止在直角处进行两次赋值(因为我的竖排横排设置的长度是一样的,在直角处会叠加) e = 0 #同变量c,是反直角使用的记录跳跃 d = 100 #同变量b,是用来反直角卡住嵌套循环的 for m in range(CS,sum-CS): if (b != sum-1-CS): for n in range(CS,sum-CS): end[n][m] = num[0] num.pop(0) #为了便于赋值,全部统一采用pop弹出列表的形式进行取值,不容易出现索引混乱 b = n #记录拐角的行数,然后为该行逐一赋值 c += 1 if(c == 1):continue #如果是拐角处(我的判断是内层循环的第一次肯定是拐角)则跳过后面的语句进行下一次循环 end[b][m] = num[0] num.pop(0) for mm in reversed(list(range(CS+1,sum-CS))): #为了便于反直角的遍历,我采用了reverse方法将列表内容进行反序,reverse是列表的方法,range没有,所以先转型 if (d != CS): for nn in reversed(list(range(CS,sum-CS-1))): end[nn][mm] = num[0] num.pop(0) d = nn e += 1 if(e == 1):continue end[d][mm] = num[0] num.pop(0) XH -= 1 CS += 1if(sum % 2 != 0): add = sum // 2 end[add][add] = num.pop() #当输入为奇数时,最中间的是个单独的一个,没有直角,所以要单独赋值 for x in range(sum): for y in range(sum): print(end[x][y],‘\t‘,end = ‘‘) print(‘\n‘) 总结:代码不长,但解决问题时想了很久,尤其是在搞循环的时候,头疼!我觉得我的方法不太好,一开时有另一个思路,但觉得有点不能实现,于是就搞了这么一个有些牵强的法子,尤其是“直角”,“反直角”的处理,墨迹了好半天。在做这个的时候遇到个好玩的事情,怎么初始化二维列表啊,因为Python也没有数组的概念,只有嵌套列表,但列表想要改值必须初始化好固定的大小的列表,否则很容易报索引超出列表范围的错。我开启的时候真不知道,只会挨个手敲,于是网上查了下,发现一个方法:end = [[0] * sum]*sum,这个写法有点让人信服哦,一个初始化为0的小列表重复n次,然后外面再把重复后得到的多个0合成的列表再重复n次得到一个含n个列表,每个列表含n个0。但是,问题来了:这个写法问题很大,第二层没什么问题,但第一层全是一个元素,举例构建2*2,得到end = [[0,0],[0,0]],当进行修改end[0][0] = 100,结果为:end = [[100,0][100,0]],原因是除了第一个元素列表,后面的元素列表是第一个的引用,即他们相当于是指针,都指向了第一个元素列表,当第一个进行修改时(改其他指针也一样),其他指针的值也会改变,因为本质上只有一个元素,正常的应该是新的指针指向新构建的元素列表,而不是直接指原来的。所以我又在同一个网页上往下看了看,发现发布者知道这个问题。。。然后我又换了新的写法:end = [[0 for i in range(6)] for i in range(6)] 这是最标准最正确的写法。内层列表,元素0,通过for循环迭代器,重复6次,得到6个0的列表,外层列表通过for循环迭代器循环6次,得到6个列表,最外层层一个列表括起来。重点在于,通过for循环迭代器方法,每次循环都是重新创建一个新的元素,而不是*那种的直接引用。说实话,这一次也给我不少教训,就上面那个初始化列表,我看了上半部分就没再往下看,当我弄完程序测试的时候屡屡出问题,我一直觉得是我的循环有问题,真没往列表方向想,然后就是拆解,一步步来,拆到最后才发现,我改一个元素整个列表都跟着变,才意识到这个列表写法有问题,如果我能一次性读完了解清楚那篇文章写得内容,那么我这么长时间的排错是完全可以避免的,毕竟时间就是金钱,时间就是生命嘛!能省时间还是省时间来的好。
原文地址:https://www.cnblogs.com/zhurs/p/11625991.html
时间: 2024-10-06 00:40:15