Loop
介紹 Python 的 for 與 while 迴圈寫法,並說明 pass、continue、break 的差異,最後以 CS50 馬力歐磚塊作業比較 C 語言的迴圈實作。
這是一系列關於我拿到天文碩士學位,我一路所學到的技能,以及我認為必須延伸的技能組的文章,技能主線會保留在 Medium 上,以中英文方式呈現,而技能支線,會以中文形式在 GitHub.io,也就是這裡發表。 預計兩邊加起來會有 27 篇文章,透過這些文章來檢核天文學位帶來給我哪些影響。
這是這系列的第二篇文章,第一篇文章Built-in Functions從 Python 內建函數開始。
在 Python 的語言當中,只有 for loop 跟 while loop。 不像其他語言可能有 do-while 或者 case 等迴圈操作。
for loop
在 for 迴圈,這概念比較像是我們已經知道會跑幾次迴圈下,會使用 for loop. 比如說:
- 我要電腦寫出 99 乘法,那我已經知道有 81 個組合要計算
- 對整個 csv 檔案寫出每一行值
- 對於迭代物件裡面的值做處理
最常見起手式就是for i in range(),因為 range 會回傳一個迭代物件,裡面就像是計數器一樣(0,1,2,3,4...),代表著這個迴圈要跑幾次一樣。
# 寫3次Hello world
for i in range(3):
print("Hello world")舉更常見的例子就是要對物件內的值做迭代處理:
animal = ['horse','turtle','mouse','donkey','lion','dragon']
for i in animal:
print(i)而如果再做共同開發,其實不僅是協作開發,自己的程式碼也應該寫的 explicitly。 什麼叫寫的 explicitly 呢? 這其實跟寫作文的風格一樣,風格含有個人的主觀想法,但大方向上應該要有個準則。 在這邊除了個人註解外,在 for loop 裡面我想要強調的是用 i 來做變數算是一個習慣(!?),因為大部分教學裡面都會用 i 來做變數,就像是我們的笛卡兒座標系一樣,我們習慣用 x, y, z 來稱呼,或者到大學後會使用 i, j, k(i 也有個說法是來表示 index。)
簡單或少量的的迴圈這樣處理可能沒問題,但當你要有兩個變數以上時,你的程式碼會越來越難讀,也就是 readability 會下降。
從下面這例子,你認為哪種方式在下週你回頭看,可以看得比較快呢?
animals = ['horse','turtle','mouse','donkey','lion','dragon']
weights = [83,2,0.4,64,140,999]
# 只使用簡單變數
for i, j in zip(animals,weights):
print(i,j)
# 明確變數內容
for animal, weight in zip(animals,weights):
print(animal, weight)另外在資料處理如果有用到 pandas,pd.DataFrame()有個內建的 iterrows(),如果要對每一列做迭代可以寫成:
for index, row in df.iterrows():
如果需要回傳物件的 index,我們也可以搭配 enumerate()使用
for index, var in enumerate(['horse','turtle','mouse','donkey','lion','dragon'])
這樣 index 就會是 0,1,2,3,4,5 而 var 會是裡面的動物名稱。
while loop
相對於 for loop,while loop 比較是在一個條件下,不停地迴圈,直到條件達成。 相較於前面知道要跑幾次之下,while 是有一個明確的目標底下在跑。
最常見讓迴圈持續不停的方法就是while True,由於預設是 true,如果沒有特別設計就不會跳出迴圈。
i = 0
while i < 5:
print("Hello World")
i = i+1
pass continue 以及 break
這三個語句是 Python 在迴圈裡面常用的操作,可以讓我們裝沒事,跳過,以及跳出迴圈。
pass
顧名思義什麼都不做。
可以是往後才要開發,所以先 pass,不然程式無法編譯。 可以是本身遇到這個情況就是選擇繼續,而不做任何改變。
animals = ['horse','turtle','mouse','donkey','lion','dragon']
for animal in animals:
if animal == 'horse':
print('neigh')
elif animal == 'turtle':
pass
elif animal == 'mouse':
print('squeak')
else:
passcontinue
中文直翻為繼續,但不要與 pass 搞混了,continue 會跳過這次迴圈,直接進入下次迴圈。
animals = ['horse','turtle','mouse','donkey','lion','dragon']
for animal in animals:
if animal == 'horse':
print('neigh')
elif animal == 'turtle':
pass
elif animal == 'mouse':
print('squeak')
elif animal == 'donkey':
continue
elif animal == 'lion':
print('roar~ roar~ roar~')
elif animal == 'dragon':
pass
>>>neigh
squeak
roar~ roar~ roar~break
break 會打破迴圈,直接終止迴圈。
animals = ['horse','turtle','mouse','donkey','lion','dragon']
for animal in animals:
if animal == 'horse':
print('neigh')
elif animal == 'turtle':
pass
elif animal == 'mouse':
break
elif animal == 'donkey':
continue
elif animal == 'lion':
print('roar~ roar~ roar~')
elif animal == 'dragon':
pass
>>>
neigh同場加映 CS50 Mario More comfortable
小小 Teaser 提供在這裡,CS50 上完之後,會有完整心得文。
在 CS50 2021 Week 1 的作業就是要用C寫來表現在馬力歐裡面的方塊。 我的答案裡面使用了兩種 loop 來達成我的目的,從中也可以比較不同語言當中,迴圈寫法有什麼差別。
這次的作業是將使用者輸入一個數字,然後做出類似馬力歐裡面磚塊的圖樣,並且做鏡像。
#include <stdio.h>
#include <cs50.h>
void pyramid(int h)
// building blocks according to height h
{
for (int i = 1; i <= h; i++)
{
// from first layer
// put space at begining
int counter = 0;
while (counter < h && counter < (h - i))
{
printf(" ");
counter++;
}
while (counter < h)
{
printf("#");
counter++;
}
// finish left part
printf(" ");
// being right part
counter = 0;
while (counter < i)
{
printf("#");
counter++;
}
while (counter < h)
{
printf("");
counter++;
}
printf("\n");
}
}
int main(void)
{
int height;
do
{
height = get_int("What's the height? ");
}
while (height < 1 || height > 8);
pyramid(height);
}