效果圖:
注意哦,右邊多出來的一點不是程序有問題,是打印的時候我用的\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 += 1
if(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循環迭代器方法,每次循環都是重新創建一個新的元素,而不是*那種的直接引用。
說實話,這一次也給我不少教訓,就上面那個初始化列表,我看了上半部分就沒再往下看,當我弄完程序測試的時候屢屢出問題,我一直覺得是我的循環有問題,真沒往列表方向想,然后就是拆解,一步步來,拆到最后才發現,我改一個元素整個列表都跟着變,才意識到這個列表寫法有問題,如果我能一次性讀完了解清楚那篇文章寫得內容,那么我這么長時間的排錯是完全可以避免的,畢竟時間就是金錢,時間就是生命嘛!能省時間還是省時間來的好。