---
# System prepended metadata

title: Lesson 2 | 條件判斷與迴圈

---

# Lesson 2 | 條件判斷與迴圈
## 第一節：熟悉資料型態(1)
在撰寫條件判斷與迴圈之前，我們先正式介紹一下Python裡面常用的內建型態（Built-in Types）。
* 布林（Boolean）：
    * True, False
* 數字類型（Numeric Types）：
    * int, float, complex
* 文本序列類型（Text sequence Type）：
    * str
* 序列類型（Sequence Types）：
    * list, tuple, range
* 集合類型（Set Types）：
    * set
* 映射類型（Mapping Types）：
    * dict

## 第一節：熟悉資料型態(2)
* 先不要被一大堆定義給嚇到，我們可以將資料型態粗略分為數字跟文字。而以下這些常用的基本函式相當重要：
    * type() - 用來查詢變數的資料型態。
    * XXX() - XXX為資料型態的名稱，用來創建或轉換資料型態。
* 首先來體驗一下"單個"的資料，我們可以使用對應到資料型態的函式來創建變數。
    * bool
        ```python=
        a = True
        print('type of a: ', type(a))
        b = bool(True)
        print('type of b: ', type(b))
        ```
        
    * int
        ```python=
        c = 16
        print('type of c: ', type(c))
        d = int(16)
        print('type of d: ', type(d))  
        ```
        
    * float
        ```python=
        e = 5.
        print('type of e: ', type(e))
        f = float(5.3)
        print('type of f: ', type(f))
        ```

    * complex
        ```python=
        g = 1+5j
        print('type of g: ', type(g))
        h = complex(1, 5)
        print('type of h: ', type(h))
        ```

    * str
        ```python=
        i = 'ABCD'
        print('type of i: ', type(i))
        j = str('ABCD')
        print('type of j: ', type(j))
        k = str('1234')
        print('type of k: ', type(k))
        ```
        
* 創建資料型態的函式也可以用來轉換資料型態。
    * 舉例來說，文本可以被轉換成數字。
        ```python=
        str_2_int = int('9452')
        print(str_2_int)
        print('type of str_2_int: ', type(str_2_int))
        
        str_2_float = float('9452.087')
        print(str_2_float)
        print('type of str_2_float: ', type(str_2_float))
        ```
        
    * 數字間int與float的轉換。
        ```python=
        float_2_int = int(9452.087)
        print(float_2_int)
        print("type of float_2_int: ", type(float_2_int))
        ```
## 第一節：熟悉資料型態(3)
* 接下來我們嘗試可以儲存"多個變數"的資料型態。

    * list

        ```python=
        list_a = [1, 2, 3, 4, "5"]
        print("type of list_a: ", type(list_a))
        ```

    * tuple - 可視為不可修改內部元素的list。

        ```python=
        tuple_a = (1, 2, 3, 4, "5")
        print("type of tuple_a: ", type(tuple_a))
        
        tuple_b = tuple([1, 2, 3, 4, "5"])
        print("type of tuple_b: ", type(tuple_b))    
        tuple_a[0] = 1 
        ```
        
    * set - 能讓輸入的元素變成"唯一"。

        ```python=
        set_a = {1, 2, 3, 4, 4}
        print(set_a)
        print("type of set_a: ", type(set_a))
        
        set_b = set([1, 87, 87, 2, 3])
        print(set_b)
        print("type of set_b: ", type(set_b))
        ```
        
    * dict - 可視為能為內部元素命名的list。
        ```python=
        dict_a = {'a': 1, 'b': 2}
        print("type of dict_a: ", type(dict_a))
        
        dict_b = dict(a = 1, b = 2)
        print("type of dict_b: ", type(dict_b))
        ```
        
* 而以下這些基本函式常在這個層級上使用：

    * len() - 用來查詢該變數的長度，變數數目。

        ```python=
        list_a = [1, 2, 3, 4, "5"]
        len(list_a)
        ```
    * range() - 則是一個比較特別的資料型態，我們常用它來創造數字序列。
        ```python=
        range_10 = range(10)
        print("type of range_10: ", type(range_10))
        print(list(range_10))
        ```

## 練習1：熟悉函數組合
* 請各位幫我查看一下這個變數。

    ```python=
    x = [16, 6, 13, 1, 3, 4, 14, 11, 11, 10, 9, 4, 6, 3, 9, 4, 2, 14, 17, 13, 16, 
         9, 6, 16, 1, 1, 9, 5, 8, 6, 14, 11, 13, 17, 3, 9, 20, 9, 11, 4, 17, 8, 3, 
         16, 8, 4, 8, 9, 20, 14, 14, 5, 14, 6, 4, 6, 6, 13, 1, 9, 6, 14, 16, 9, 20, 
         16, 9, 13, 13, 4, 2, 5, 8, 14, 18, 16, 16, 4, 18, 11, 18, 11, 10, 6, 5, 17, 
         9, 11, 13, 20, 8, 8, 16, 9, 13, 4, 3, 17, 16, 9, 6, 8, 3, 8, 2, 20, 11, 14, 
         16, 8, 11, 13, 1, 4, 20, 16, 17, 3, 16, 5, 20, 20, 5, 4, 5, 16, 6, 11, 10, 
         2, 17, 13, 18, 2, 13, 2, 9, 2, 9, 13, 16, 8, 5, 11, 6, 18, 9, 9, 5, 11, 1, 
         8, 5, 2, 9, 16, 1, 3, 5, 6, 2, 1, 9, 16, 20, 6, 4, 6, 8, 3, 5, 13, 17, 6, 1, 
         6, 4, 9, 6, 6, 5, 5, 5, 17, 8, 13]
    ```
    * 問題1：在變數「x」內有共幾「個」數字?

        <details>
      <summary>解答</summary>
    
      - 答案為186。
      ```python=
      print(len(x))
      ```
        </details>
        
    * 問題2：共有幾「種」數字在變數「x」內?

        <details>
      <summary>解答</summary>
    
      - 我們可以利用set()，來讓list內的元素變成唯一，答案為16。
      ```python=
      print(len(set(x)))
      ```
        </details>
        
    * 問題3：這個數列中缺少了1至20中的哪些數字?

        <details>
      <summary>解答</summary>
    
      - 這題比較特別，我們可以用肉眼觀察，答案為7、12、15、19。倘若內容物的數字數以百計呢？就需要用到接下來這堂課要介紹的『條件判斷與迴圈』。
      ```python=
      print(set(x))
      ```
        </details>
        
## 第二節：條件判斷式(1)

* 在Python裡面，要做判斷，常用這幾種「運算」，來回傳布林。

    * 布林運算（Boolean Operations）：「or」、「and」、「not」、「in」。

      ```python=
      x = True
      y = False
      # "or" - 或
      print(x or y)
      # "and" - 且
      print(x and y)
      # "not" - 不是
      print(not x)
      # "in" - 在不在裡面
      print(x in [False, False, False, False])
      ```
      
    * 比較運算（Comparisons Operations）：「<」、「<=」、「>」、「>=」、「==」、 「!=」。

      ```python=
      print(1 < 2)
      print(2 == 1 + 1)
      print("Z" > "B")
      print("同婚" != "性解放")
      ```

* 我們可以利用這些「運算」的組合，來做更複雜的判斷。

  ```python=
  x = 9
  print(x <= 4 and x > 2)
  print(x > 4 or x <= 2)
  ```
  
## 第二節：條件判斷式(2)

* 讓我們來正式介紹條件判斷式，使用在複合語句（Compound Statements）當中的「if」。當「if」後為真時，Python會執行冒號後的程式碼。

    * 若A，若A則B。
    
        ```python=
        if "Z" > "B":
            x = 2

        if "利" > "弊":
            y = 3
        else:
            y = 4

        print(x * y)
        ```
    
    * 若不是則。
        ```python= 
        score = 99
        if score >= 90:
            print('A')
        elif score >= 75: # else if
            print('B')
        elif score >= 60: # else if
            print('C')
        else:
            print('Not pass.')
        ```
    
## 練習2：熟悉條件判斷式

* 我們現在已經可以利用我們所學，建構簡單的應用腳本。請同學們參考[國民健康署網站](https://www.hpa.gov.tw/Pages/Detail.aspx?nodeid=542&pid=705)，建立一個BMI指數計算器，以變數儲存身高與體重，讓Python回傳其BMI數值以及體重是否正常，回傳的文字包含"體重過輕"、"健康體重"、"體重過重"或是"肥胖"。

    <details>
  <summary>解答</summary>

    ```python=
    height = 163
    weight = 60
    BMI = (weight / ((height/100)**2))
    print("你輸入的BMI為", BMI, " (kg/m^2).")
    if BMI < 18.5:
        result = '體重過輕'
    elif BMI < 24:
        result = '健康體重'
    elif BMI < 27:
        result = '體重過重'
    else:
        result = '肥胖'
    print("體重狀況: ", result)
    ```

    </details>

## 第二節：迴圈(1)

* 如果我們要對大量的資料進行重複的計算或判斷呢？
    
* 讓我們觀察「費波納奇數列」：起始數列為1、1，之後每個數為前兩個數之和。
    
    ```python=
    # 這是一個常用來複製list的方式
    x = [0] * 12
    # 將前兩個數字皆替換成1。
    x[0:2] = 1, 1
    
    x[2] = x[1] + x[0]
    x[3] = x[2] + x[1]
    x[4] = x[3] + x[2]
    x[5] = x[4] + x[3]
    x[6] = x[5] + x[4]
    x[7] = x[6] + x[5]
    x[8] = x[7] + x[6]
    x[9] = x[8] + x[7]
    x[10] = x[9] + x[8]
    x[11] = x[10] + x[9]
    
    print(x)
    ```
    
    * 你是否覺得這樣的運算存在規律？而要怎樣抽解這些規律呢？
    
* 在上述程式碼我們注意到了一件事情，也就是每一行程式碼中索引的位置都會一起增加1。我們現在將使用另一個變數來替換程式碼中共同的部分。
    
    ```python=
    # 創建一個長度為12，元素皆為0的list。
    x = [0] * 12
    # 將前兩個數字皆替換成1。
    x[0:2] = 1, 1

    idx = 2
    x[idx] = x[idx - 1] + x[idx - 2]
    idx = 3
    x[idx] = x[idx - 1] + x[idx - 2]
    idx = 4
    x[idx] = x[idx - 1] + x[idx - 2]
    idx = 5
    x[idx] = x[idx - 1] + x[idx - 2]

    print(x)
    ``` 
    
    * 若能定義好變數，讓變數依序改變，我們即可讓程式進行大量運算，這是迴圈的基本邏輯！

## 第二節：迴圈(2)
    
* 讓我們正式介紹第二個常用的複合語句：「for」，「for」會搭配另外一個運算：「in」使用。
    
* 我們可以把for迴圈翻譯成"讓...在...裡面，使其從頭到尾依序指派..."。
    
* 這個時候先不要急，我們先藉由這些下列程式碼來理解迴圈。
    * 先宣告一個list來存idx，然後我們使用「for」，在for迴圈內會依序指派「in」後面的變數。
    
        ```python=
        idx_list = list(range(10))
        print(idx_list)

        for idx in idx_list:
            print(idx)
        ```
    
    * 我們也可以直接使用range()，range這個資料型態能直接用於迴圈。
    
        ```python=
        for idx in range(10):
            print(idx)    
        ```
    
* 讓我們回到「費波納奇數列」，我們先宣告物件，並使用迴圈進行運算。
    
    ```python=
    len_of_num = 12
    # 創建長度為12，元素皆為0的list。
    x = [0] * len_of_num
    # 將前兩個數字皆替換成1。
    x[0:2] = 1, 1
    print(x)

    # 使用迴圈更替idx，並依序執行程式碼。
    for idx in range(2, len_of_num):
        x[idx] = x[idx - 1] + x[idx - 2]
    print(x)
    ``` 

## 第二節：迴圈(3)
    
*  上述程式碼的實際運作，其實是依序重複執行迴圈內的程式碼
*  因此在第一個迴圈中Python其實是做了以下的事情。
    
    * 在第一圈時，變數idx被指定為以range()所產生的第一個內容「2」。
    
        ```python=
        idx = 2
        x[idx] = x[idx - 1] + x[idx - 2]
        ```    
    
    * 第二迴圈則是令idx為range中的第二個數字3。
    
        ```python=
        idx = 3
        x[idx] = x[idx - 1] + x[idx - 2]
        ```
    
    * 依此類推，到最後一個迴圈時則是令idx = 11。
    
        ```python=
        idx = 11
        x[idx] = x[idx - 1] + x[idx - 2]        
        ```

* 同學們是否覺得迴圈其實很簡單呢？

## 第二節：迴圈(4)
    
* 迴圈所指派的變數不見得必須是數字，例如也可以是文本，下面是一個合併迴圈與判斷的範例。
    
    * 我們可以讓Python告訴我們這些單字有哪些英文字母的字數大於等於5。
    
        ```python=
        words = ['cat', 'window', 'defenestrate']
        for w in words:
            if len(w) >= 5:
                print(w, len(w))      
        ```
    
    * 以下範例也是一種常用來索引內容物以及處理資料的演算法。

        ```python=
        a = ['Mary', 'had', 'a', 'little', 'lamb']
        for i in range(len(a)):
            print(i, a[i])      
        ```    
    
## 練習3：迴圈與條件判斷的組合
* 現在我們已經有更好的方式可以回答本堂課練習1中的問題3。
    ```python=
    x = [16, 6, 13, 1, 3, 4, 14, 11, 11, 10, 9, 4, 6, 3, 9, 4, 2, 14, 17, 13, 16, 
         9, 6, 16, 1, 1, 9, 5, 8, 6, 14, 11, 13, 17, 3, 9, 20, 9, 11, 4, 17, 8, 3, 
         16, 8, 4, 8, 9, 20, 14, 14, 5, 14, 6, 4, 6, 6, 13, 1, 9, 6, 14, 16, 9, 20, 
         16, 9, 13, 13, 4, 2, 5, 8, 14, 18, 16, 16, 4, 18, 11, 18, 11, 10, 6, 5, 17, 
         9, 11, 13, 20, 8, 8, 16, 9, 13, 4, 3, 17, 16, 9, 6, 8, 3, 8, 2, 20, 11, 14, 
         16, 8, 11, 13, 1, 4, 20, 16, 17, 3, 16, 5, 20, 20, 5, 4, 5, 16, 6, 11, 10, 
         2, 17, 13, 18, 2, 13, 2, 9, 2, 9, 13, 16, 8, 5, 11, 6, 18, 9, 9, 5, 11, 1, 
         8, 5, 2, 9, 16, 1, 3, 5, 6, 2, 1, 9, 16, 20, 6, 4, 6, 8, 3, 5, 13, 17, 6, 1, 
         6, 4, 9, 6, 6, 5, 5, 5, 17, 8, 13]
    ```
    
    * 問題1：這個數列中缺少了1至20中的哪些數字?請利用迴圈與判斷。

        <details>
      <summary>解答</summary>
            
        ```python=
        uni_x = set(x)
        for idx in list(range(1, 21)):
            if idx not in uni_x:
                print("缺少了", idx)
        ```
        </details>
     
* 費波納奇數列是起始數列為1、1，之後每個數為前兩個數之和。現在，我們來創造一個NDMC數列，其定義是起始數列為1、1，之後第三個數字（奇數）為前兩個相加，第四個數字（偶數）為前兩個數字相乘，第五個數字（奇數）為前兩個相加，依此類推
    
    ```python=
    # 創建長度為10，元素皆為0的list。
    len_of_num = 10
    x = [0] * len_of_num
    # 將前兩個數字皆替換成1。
    x[0:2] = 1, 1
    print(x)
    ```
    
    * 問題2：請用迴圈功能完成它（小心奇偶數順序時，要做的動作不同，請同學思考如何利用條件判斷來完成這個問題）。

    
        <details>
      <summary>解答</summary>
        
        - 這題其實有很多解法，解法一相對直觀。
        ```python=
        for idx in range(2, len_of_num):
            if idx % 2 == 0:
                x[idx] = x[idx - 1] + x[idx - 2]
            else:
                x[idx] = x[idx - 1] * x[idx - 2]
        
        print(x)
        ```
            
        - 解法二相對不直觀，但也是一種思考模式。
        ```python=
        for idx in range(1, int(len_of_num/2)):
            x[2*idx] = x[2*idx - 1] + x[2*idx - 2]
            x[2*idx+1] = x[2*idx] * x[2*idx - 1]
        
        print(x)
        ```        

        </details>

## 第三節：巢狀迴圈(1)

迴圈的美妙之處在於能夠大量且依序運算，我們將透過迴圈進行更複雜的組合任務：巢狀迴圈（Nested for-loop）。

* 現在讓我們想辦法列出2到6內所有的「質數」。
* 何謂質數？質數為找不到比自己更小的可整除除數，如5以下的數字為2、3、4，而5無法被這些數字整除。
* 現在讓我們思考該如何回答這個的問題。

## 第三節：巢狀迴圈(2)

* 我們先產生一個變數x儲存2至6的所有數字，再創建answer變數表示變數x中相對應的元素是否為質數，而answer皆預設為True

    ```python=
    x = list(range(2, 7))
    answer = [True] * len(x)
    ```

* 讓我們一步一步來思考，可以先從3開始。
    
    ```python=
    # 對3進行檢測(x物件中的第2個數字)
    if x[1] % x[0] == 0: answer[1] = False
    
    # 對4進行檢測(x物件中的第3個數字)
    if x[2] % x[0] == 0: answer[2] = False
    if x[2] % x[1] == 0: answer[2] = False
    
    # 對5進行檢測(x物件中的第4個數字)
    if x[3] % x[0] == 0: answer[3] = False
    if x[3] % x[1] == 0: answer[3] = False
    if x[3] % x[2] == 0: answer[3] = False
    
    # 對6進行檢測(x物件中的第5個數字)
    if x[4] % x[0] == 0: answer[4] = False
    if x[4] % x[1] == 0: answer[4] = False
    if x[4] % x[2] == 0: answer[4] = False
    if x[4] % x[3] == 0: answer[4] = False
    ```

* 這樣我們可以透過answer來索引x，得到6以下的質數：

    ```python=
    for idx in range(len(x)):
        if answer[idx]:
            print(x[idx])
    ```

## 第三節：巢狀迴圈(3)

* 聰明的你是不是已經發現某些規律，我們可以先利用變數取代部分索引的數字。

    ```python=
    # 宣告變數
    x = list(range(2, 7))
    answer = [True] * len(x)
    
    i = 1
    # 對3進行檢測(x物件中的第2個數字)
    if x[i] % x[0] == 0: answer[i] = False
    
    i = 2
    # 對4進行檢測(x物件中的第3個數字)
    if x[i] % x[0] == 0: answer[i] = False
    if x[i] % x[1] == 0: answer[i] = False
    
    i = 3
    # 對5進行檢測(x物件中的第4個數字)
    if x[i] % x[0] == 0: answer[i] = False
    if x[i] % x[1] == 0: answer[i] = False
    if x[i] % x[2] == 0: answer[i] = False
    
    i = 4
    # 對6進行檢測(x物件中的第5個數字)
    if x[i] % x[0] == 0: answer[i] = False
    if x[i] % x[1] == 0: answer[i] = False
    if x[i] % x[2] == 0: answer[i] = False
    if x[i] % x[3] == 0: answer[i] = False    
    ```

    * 可以發現對於每個數字，檢查是否整除的程式碼行數不同，而越後面的數字行數越多。

## 第三節：巢狀迴圈(4)
    
* 這時同學們是不是其實已經想到，我們可以再撰寫一個內圈（inner loop）。
    
    * 我們可以先這樣理解，將內圈以變數j替代。
    
        ```python=
        # 宣告變數
        x = list(range(2, 7))
        answer = [True] * len(x)

        # 外圈：對3進行檢測(x物件中的第2個數字)
        i = 1
        # 內圈
        j = 0
        if x[i] % x[j] == 0: answer[i] = False

        # 外圈：對4進行檢測(x物件中的第3個數字)
        i = 2
        # 內圈
        j = 0
        if x[i] % x[j] == 0: answer[i] = False
        j = 1
        if x[i] % x[j] == 0: answer[i] = False

        # 外圈：對5進行檢測(x物件中的第4個數字)
        i = 3
        # 內圈
        j = 0
        if x[i] % x[j] == 0: answer[i] = False
        j = 1
        if x[i] % x[j] == 0: answer[i] = False
        j = 2
        if x[i] % x[j] == 0: answer[i] = False

        # 外圈：對6進行檢測(x物件中的第5個數字)
        i = 4
        # 內圈
        j = 0
        if x[i] % x[j] == 0: answer[i] = False
        j = 1
        if x[i] % x[j] == 0: answer[i] = False
        j = 2
        if x[i] % x[j] == 0: answer[i] = False
        j = 3
        if x[i] % x[j] == 0: answer[i] = False    
        ```
    
* 讓我們先關注於6的部分，似乎可以將這些程式碼合成一個迴圈。
    
    ```python=
    # 外圈：對6進行檢測(x物件中的第5個數字)
    i = 4
    # 內圈
    for j in range(4):
        if x[i] % x[j] == 0: answer[i] = False
    ```
    
* 找到內圈的規律後，我們將其推廣到外圈（outer loop），並且對於每個j剛好到i-1。
    
    ```python=
    # 宣告變數
    x = list(range(2, 7))
    answer = [True] * len(x)

    # 外圈：對3進行檢測(x物件中的第2個數字)
    i = 1
    # 內圈
    for j in range(i):
        if x[i] % x[j] == 0: answer[i] = False

    # 外圈：對4進行檢測(x物件中的第3個數字)
    i = 2
    # 內圈
    for j in range(i):
        if x[i] % x[j] == 0: answer[i] = False

    # 外圈：對5進行檢測(x物件中的第4個數字)
    i = 3
    # 內圈
    for j in range(i):
        if x[i] % x[j] == 0: answer[i] = False

    # 外圈：對6進行檢測(x物件中的第5個數字)
    i = 4
    # 內圈
    for j in range(i):
        if x[i] % x[j] == 0: answer[i] = False
    ```    
    
## 練習4：巢狀迴圈與條件判斷的組合
    
* 同學們應該已經有能力完成接下來的步驟，透過巢狀迴圈列出2到6內所有的「質數」，並有能力推廣到更多的數目。

    * 問題1：請試著理解剛剛的每一個過程，並撰寫巢狀迴圈找出100以下的質數有哪些。

        <details>
      <summary>解答</summary>
        
        - 同學們其實可以發現range(0)是不會進入內圈的，所以下列的程式碼會看起來更簡潔。
        ```python=
        num_to_slove = 101
        # 宣告變數
        x = list(range(2, num_to_slove))
        answer = [True] * len(x)

        for i in range(len(x)):
            for j in range(i):
                if x[i] % x[j] == 0: 
                    answer[i] = False

        for idx in range(len(x)):
            if answer[idx]:
                print(x[idx])       
        ```
        </details>
    
    
    * 問題2：事實上質數可以再更精確的定義為找不到比自己更小的可整除的「質數」，如5以下的「質數」為2、3，因此在檢查5的時候我們其實不需要檢查4這個數字。

        <details>
      <summary>解答</summary>
        
        - 除此之外，「break」語句能夠提早終止迴圈。
        ```python=
        num_to_slove = 101
        # 宣告變數
        x = list(range(2, num_to_slove))
        answer = [True] * len(x)

        for i in range(len(x)):
            for j in range(i):
                if answer[j]:
                    if x[i] % x[j] == 0: 
                        answer[i] = False
                        break

        for idx in range(len(x)):
            if answer[idx]:
                print(x[idx])       
        ```
        </details>

## 總結
* 同學們請回去務必練習並熟悉這些相關的程式語法。
    * 資料型態轉換。
    * 條件判斷式。
    * 迴圈。
* 這堂課主要在教導如何撰寫條件判斷式與迴圈，同學們應該已有能力用Python處理許多任務。
* 熟悉迴圈指令將能夠讓電腦幫你處理許多常規的重複工作！    
    
   
    
