---
# System prepended metadata

title: Python 基礎語法 ① - 資料型態與變數
tags: [Python, tutorial]

---

# Python 基礎語法 ① - 資料型態與變數
![python-banner](https://hackmd.io/_uploads/BJX5vWrwex.png)
:::info
[toc]
:::

<br/>

🐍 Python 中，**資料**皆有其對應的**型態**，要儲存資料以重複使用則需要一個++被命名的記憶體空間++ 稱之為**變數 (Variable)**，此外不需要宣告資料型別，直接賦值即可。
- ![image](https://hackmd.io/_uploads/ByJ_uNHwlx.png)

<br/>

## 資料型態

:::success
前言: Everything in python is an object (物件)
> 💡++物件就是一種模板/類別的實體，想像成一個完善的產品，有很多功能可以用++
:::

資料型態是 Python Intepreter(解譯器) 在辨別資料格式時會參照的規則，並將其分為五大類:
> 想必然 Python 的各個資料型態，也皆是不同類別的物件!

<br/>

- 各資料型態範例一覽：
```python
'''python 單行程式碼 結尾是不必要加上分號的'''

x = 10       # 整數 int
y = 3.14     # 浮點數 float
z = 3 + 4j   # 複數 complex
name = "Amy" # 字串 str
is_ok = True # 布林值 bool
my_list = [2, '4', 6, [8, "10"]] # 列表 list
my_tuple = (1, "3", 5, (7, '9')) # 元組 tuple
my_set = {1, 2, 3} # 集合 set
my_dict = { 'apple': 5, 'banana': 2 } # 字典

print(type(...)) """在 python 可利用 type(object) 函式來查看物件類別"""
```

<br/>

### 1️⃣ Numeric (數值)
能夠進行++算術運算++( `+`、`-`、`*`、`**`、`/`、`//`、`%` ) 執行基本數學計算的資料型態。 
1. **Integer `int`**: 所有整數都被實現為任意大小的「長整數」物件。
    - `int(value, base=10)` 函式: 返回++整數物件++。
        - `value`: 數字 or 字串(能夠被轉換成整數的)。
        - `base`: 數值的進位制，預設為十進位。

    :::spoiler 常見內建方法
    - `.bit_length()`: 計算二進位數位元數。
    - `.bit_count()`: 計算二進位數中 1 bit 數量。
    - `.to_bytes(length, byteorder, *, signed=False)`: 返回代表數字的位元組數組。
        ```python
        # 範例
        num = 128
        print(num.to_bytes(2, 'big'))    # Output: b'\x00\x80'
        print(num.to_bytes(2, 'little')) # Output: b'\x80\x00' 
        ```
    - `.from_bytes(bytes, byteorder, *, signed=False)`: 返回代表位元組數組的數字。
        ```python
        # 範例
        byte_data = b'\x02\x01'
        print(int.from_bytes(byte_data, 'big'))    # Output: 513
        print(int.from_bytes(byte_data, 'little')) # Output: 258 
        ```
    :::
    ---

2. **Float `float`**: 浮點數數值，用於表示實數，可以包括整數或小數部分。
    - `float(value)` 函式: 返回++浮點數物件++。
        - `value`: 數字 or 字串(能夠被轉換成浮點數的)。

    :::spoiler 常見內建方法
    - `.is_integer()`: 返回 `True` 如果數值小數點部分，否則 `False`。
    - `.as_integer_ratio()`: 返回一對整數(元組)，代表最簡分數**分子**與**分母**。
    - `.hex()`: 返回浮點數十六進位制表示法的數值以字串表示。
    - `float.fromhex(string)`: 返回十六進位制數值字串的浮點數數值。
        ```python
        # 範例
        hex_str = '0x1.5000000000000p+3'
        print(float.fromhex(hex_str)) # Output: 10.5
        ```
    :::
    ---

3. **Complex Number `complex`**: 表示複數，包含++實部++和++虛部++。
    - `complex(value, imag)` 函式: 返回++浮點數物件++。
        - `value`: 指定複數的實部 (默認為0)。
        - `imag`: 指定複數的虛部 (默認為0)。
            ```python
            # 也可以從字符串創建複數
            num4 = complex('1+2j')
            print(num4)  # 輸出: (1+2j)
            ```
        
    > `complex` object 並未有許多內建方法，考慮用 `cmath` module 來做複數數學操作。
    :::spoiler `cmath` 範例
    ```python
    import cmath

    z = 1 + 1j
    modulus, phase = cmath.polar(z)
    print("Modulus: ", modulus)
    print("Phase: ", phase)

    sqrt_z = cmath.sqrt(z)
    print("Square root: ", sqrt_z)
    ```
    :::
    ---

<br/>

###  2️⃣ Boolean (布林值)
在 python 中，`bool` 是 `int` 的 subclass，因此 `True` 可以被當作是 `1`，而 `False` 則是 `0`，除了從 `int` 繼承的方法和所有 Python 物件共有的基本物件方法之外，`bool` 物件++本身沒有獨特的內建方法++。
- `bool(object)` 函式: 將給定物件(值) 轉換為其對應的布林表示形式。
    - `object`: 可接受任何類型物件輸入。

- ==假值==評估: `False`、`None`、數字零(`0`, `0.0`, `0j`)、空字串(`""`)、空數組(`()`、`[]`、`{}`)、`Object.__bool__()->False`、`Object.__len__()->0`
- ++真值++評估: 所有其他值均視為真值，`bool()` 會傳回 `True`。這包括非空字串、非零數字、非空列表、元組、字典以及大多數自訂物件。

<br/>

### 3️⃣ Sequence (序列) 

:::spoiler 序列相關函數
- `len(sequence_object)`: 返回物件的元素個數。
- `max(sequence_object)`: 返回物件中的最大值。
- `min(sequence_object)`: 返回物件中的最小值。
- `sum(sequence_object)`: 返回物件中的所有元素之和(僅適用於數字序列)。
- `sorted(sequence_object, reverse=Fasle)`: 返回一個新的已排序的序列，不修改原始列表; `reverse` 參數決定是否大的數值在前，否則以小排到大。
:::

1. String `str`:
由無意義字元所組成的資料型態，以單引號 `'` 或 雙引號 `"` 包覆，內含大量內建功能，包括用於操作、分析和格式化字串等等。
    - `str(object)` 函式: 用於將其他數據類型轉換為字符串，並返回該對象的字符串表示形式。
        - `object`: 可接受任何類型物件輸入。

    :::spoiler `str()` 使用範例
    ```python
    # 將整數轉換為字符串
    num = 123
    num_str = str(num)
    print(type(num_str))  # 輸出: <class 'str'>
    print(num_str)       # 輸出: 123

    # 將浮點數轉換為字符串
    float_num = 3.14
    float_str = str(float_num)
    print(type(float_str)) # 輸出: <class 'str'>
    print(float_str)      # 輸出: 3.14

    # 將布林值轉換為字符串
    bool_val = True
    bool_str = str(bool_val)
    print(type(bool_str)) # 輸出: <class 'str'>
    print(bool_str)      # 輸出: True

    # 將列表轉換為字符串
    my_list = [1, 2, 3]
    list_str = str(my_list)
    print(type(list_str)) # 輸出: <class 'str'>
    print(list_str)      # 輸出: [1, 2, 3]

    # 將字典轉換為字符串
    my_dict = {'a': 1, 'b': 2}
    dict_str = str(my_dict)
    print(type(dict_str)) # 輸出: <class 'str'>
    print(dict_str)      # 輸出: {'a': 1, 'b': 2}
    ```
    :::

    > 🔗 String 內建方法: [Python String Methods](https://www.w3schools.com/python/python_ref_string.asp)
    ---

<br/>

2. List `list`:
儲存++多個元素++(多維資料)的資料型態，這些元素可以是不同的資料型態，並且可以重複。列表通過方括號 `[]` 來表示並且內容是可改變的，這意味可以修改列表中的元素、新增元素或移除元素 (CRUD)。
    - `list(iterable)` 函式: 將一個可疊代物件(例如字串、元組或集合) 轉換為列表。
    :::spoiler 常見內建方法
    - `append(element)`: 將一個元素添加到列表的末尾。
    - `insert(index, element)`: 在指定的索引位置插入一個元素。
    - `extend(another_list)`: 將另一個列表的所有元素添加到當前列表的末尾。
    - `remove(element)`: 移除列表中第一個匹配到的元素。
    - `pop([index])`: 移除並返回指定索引位置的元素，如果不指定索引，則移除並返回列表的最后一个元素。
    - `index(element)`: 返回列表中第一個匹配到的元素的索引。
    - `count(element)`: 返回列表中某個元素出现的次数。
    - `sort(reverse=False)`: 對列表中的元素進行排序，默認升序，可以使用 `reverse=True` 做反序排序。
    - `reverse()`: 反轉列表中的元素順序。
    - `copy()`: 返回列表的淺拷貝。
    - `clear()`: 移除列表中的所有元素。
    ```python
    # 範例
    my_list = [1, 2, 3, 'apple', 'banana']

    # 列表長度
    print(len(my_list))  # 輸出: 5

    # 添加元素
    my_list.append(4)
    print(my_list)  # 輸出: [1, 2, 3, 'apple', 'banana', 4]

    # 插入元素
    my_list.insert(2, 'orange')
    print(my_list)  # 輸出: [1, 2, 'orange', 3, 'apple', 'banana', 4]

    # 移除元素
    my_list.remove('apple')
    print(my_list)  # 輸出: [1, 2, 'orange', 3, 'banana', 4]

    # 移除並返回元素
    removed_element = my_list.pop(1)
    print(my_list)  # 輸出: [1, 'orange', 3, 'banana', 4]
    print(removed_element) # 輸出: 2

    # 排序
    numbers = [3, 1, 4, 1, 5, 9, 2, 6]
    numbers.sort()
    print(numbers) # 輸出: [1, 1, 2, 3, 4, 5, 6, 9]

    # 反轉
    numbers.reverse()
    print(numbers) # 輸出: [9, 6, 5, 4, 3, 2, 1, 1]

    # 拷貝
    new_list = my_list.copy()
    print(new_list) # 輸出: [1, 'orange', 3, 'banana', 4]

    # 清空
    my_list.clear()
    print(my_list) # 輸出: []
    ```
    :::
    ---

3. Tuple `tuple`:
類似列表型態，但是元組物件是++不可變序列++，且其內建方法有限。
    - `tuple(iterable)`: 接受一個可迭代物件並將其元素轉換為不可變的元組 (_Read-Only_)。
    ```python
    # 範例
    # creating empty tuple
    empty_tuple1 = ()
    empty_tuple2 = tuple()
    print(empty_tuple1, empty_tuple2)
    
    # creating a tuple from a list.
    my_list = [1, 2, 3]
    new_tuple = tuple(my_list)
    print(new_tuple) # output: (1, 2, 3)
    
    # creating a tuple from a string.
    my_string = "Python"
    char_tuple = tuple(my_string)
    print(char_tuple) # output: ('P', 'y', 't', 'h', 'o', 'n')
    ```
    - 主要方法:
        - `tuple.count(value)`: 回傳指定值在元組中出現的次數。
        - `tuple.index(value, start=0, end=len(tuple))`:
        回元組中指定值++首次++出現的索引。可以傳入可選的 `start` 和 `end` 參數，以便在元組的特定切片內進行搜尋。如果未找到該值，則會引發 `ValueError` 錯誤。
    ---

<br/>

### 4️⃣ Set (集合)
集合用於儲存++無序++且++不重複++的元素集合。是可以變動的，也意味著可以新增或移除元素。集合的特性使其適合於執行諸如求交集、聯集、差集等數學集合運算。

- `set(iterable)` 函式:
將可迭代物件轉換為集合，自動去除重複的元素，並返回新的集合物件。 

    ```python
    # 範例
    # creating empty set
    empty_set1 = {}
    empty_set2 = set()
    print(empty_set1, empty_set2)  # output: {} set()
    
    # creating a set from a list.
    my_list = [1, 2, 2, 3, 4, 4, 4, 5]
    my_set = set(my_list)
    print(my_set)  # 輸出: {1, 2, 3, 4, 5} (順序可能不同)
    
    # creating a set from a string.
    my_string = "hello"
    my_set = set(my_string)
    print(my_set)  # 輸出: {'h', 'e', 'l', 'o'} (順序可能不同)
    ```
    :::spoiler 常見內建方法
    <br/>
    
    | 函式 | 集合方法 |
    |-|-|
    | `add(element)` | 在集合中加入指定元素。如果該元素已存在，則集合保持不變。 |
    | `clear()` | 從集合中刪除所有元素，使其成為空集合。 |
    | `copy()` | 傳回集合的淺拷貝。 |
    | `pop()` | 從集合中移除並傳回任意一個元素。由於集合是無序的，因此無法保證移除的是哪個元素。如果集合為空，則會引發 `KeyError`。 |
    | `remove(element)` | 從集合中刪除指定元素。如果未找到該元素，則引發 KeyError。 |
    | `discard(element)` | 如果存在，則從集合中移除指定元素。與 `remove()` 不同，如果找不到該元素，則不會引發 `KeyError`。 |
    | `difference(other_set)` | 傳回一個新集合，其中包含原始集合中存在但不存在於 `other_set` 中的元素。此操作也可以使用 ==-== 運算子實作。 |
    | `difference_update(other_set)` | 從原始集合中刪除在 `other_set` 中也存在的元素。這會對集合進行修改。也可以使用 ==-\=== 運算子實現此操作。 |
    | `union(other_set)` | 傳回一個包含原始集合和 `other_set` 中所有唯一元素的新集合。也可以使用 ==\|== 運算子實作。 |
    | `update(other_set)` | 將 `other_set` 中所有唯一元素加入到原始集合中。這會就地修改集合。也可以使用 ==\|\=== 運算子來實現此操作。 |
    | `issuperset(other_set)` | 如果 `other_set` 的所有元素都存在於原始集合中，則傳回 `True`，否則傳回 `False`。這也可以使用 ==>\=== 運算子實現。 |
    | `issubset(other_set)` | 如果原始集合的所有元素都存在於 `other_set` 中，則傳回 `True`，否則傳回 `False`。這也可以使用 ==<\=== 運算子實現。 |
    | `intersection(other_set)` | 傳回一個新集合，其中包含原始集合和 `other_set` 共有的元素。也可以使用 ==&== 運算子實作。 |
    | `intersection_update(other_set)` | 透過只保留原始集合和 `other_set` 共有的元素來更新原始集合。這會就地修改集合。也可以使用 ==&\=== 運算子來實現。 |
    | `symmetric_difference(other_set)` | 傳回一個新集合，該集合包含原集合或 `other_set` 中的元素，但不同時存在於兩者中。此操作也可以使用 ==^== 運算子實現。 |
    | `symmetric_difference_update(other_set)` | 更新原始集合，僅保留原始集合或 `other_set` 中存在的元素，但不同時存在於兩者中。這會就地修改集合。此操作也可以使用 ==^\=== 運算子實現。 |
    | `isdisjoint(other_set)` | 如果集合與 `other_set` 沒有共同的元素，則傳回 `True`，否則傳回 `False`。 |
    :::
    
<br/>

### 5️⃣ Dictionary (字典)
字典是一個儲存許多鍵與值配對的資料型態，物件提供了多種與其++鍵值對++互動的方法。這些方法允許執行各種操作，包括新增、刪除、存取和迭代元素。
- `dict(keyword arguments,)` 函式: 用於建立並返回字典物件。字典是一個可變的、無序的鍵值對集合，其中每個鍵都是唯一的，並映射到一個特定的值 (Hash Table)。
    - `key1=arg1, key2=arg2`:Optional。可設定任意數量的關鍵字參數與值配對，並以逗號分隔：`key = value, key = value ...`
    ```python
    # 範例
    # creating empty dictionary
    my_dict = dict()
    
    # Creating a dictionary from keyword arguments.
    person = dict(name="Alice", age=30, city="New York")
    
    # Creating a dictionary from an iterable of key-value pairs (e.g., a list of tuples)
    data = [('one', 1), ('two', 2), ('three', 3)]
    numbers = dict(data)
    
    # Creating a dictionary from a mapping object (e.g., another dictionary)
    original_dict = {'a': 1, 'b': 2}
    new_dict = dict(original_dict)
    ```
> 🔗 Dictionary 內建方法: [Python Dictionary Methods](https://www.w3schools.com/python/python_ref_functions.asp)


<br/>

## 變數
Python 中，**變數** 是儲存資料的容器，它們可以被賦予一個名稱，以便在程式碼中引用和操作。 變數可以儲存不同型別的資料，並且可以在程式執行過程中改變其值。

1. 基本概念
    - **儲存資料**: 變數就像一個標籤，指向記憶體中儲存資料的位置。 
    - **動態型別**: 變數是動態型別的，這意味不需要明確宣告變數的資料型別，Python 會根據賦予的值自動判斷。 
    - **可變性**: 變數的值可以在程式執行過程中改變。 

2. 變數的命名規則
    - 變數名稱必須以字母或底線開頭。
    - 變數名稱可以包含字母、數字和底線。
    - 變數名稱不能以數字開頭。
    - 變數名稱是區分大小寫的 (e.g: `age` 和 `Age` 是不同的變數)。

3. 範例
    ```python
    # 定義一個整數變數
    x = 10
    print(x)  # 輸出: 10

    # 定義一個字串變數
    name = "Alice"
    print(name) # 輸出: Alice

    # 多重賦值
    x, y, z = "Orange", "Banana", "Cherry"
    print(x, y, z)
    
    # 改變變數的值
    x = 20
    print(x)  # 輸出: 20

    # 使用更具描述性的變數名稱
    student_name = "Bob"
    print(student_name) # 輸出: Bob
    ```

4. 賦與拷貝
在 Python 中，**變數本質上是參考（Reference）記憶體中的資料**，這表示：
    ```python
    a = [1, 2, 3]
    b = a
    b[0] = 100
    print(a)  # [100, 2, 3] ❗️a 也跟著被改變了
    ```
    :::warning
    因為 `b = a` 是讓 `b` 指向和 `a` 同一個 list，而不是複製內容！
    :::
    
    a. **Shallow Copy** (淺拷貝) 範例
    ```python
    import copy

    a = [[1, 2], [3, 4]]
    b = copy.copy(a)

    b[0][0] = 999
    print(a)  # [[999, 2], [3, 4]] ❗️內層仍連動
    
    '''外層 list 被複製，但內層仍然是同一個物件'''
    ```
    
    b. **Deep Copy** (深拷貝) 範例
    ```python
    import copy

    a = [[1, 2], [3, 4]]
    b = copy.deepcopy(a)

    b[0][0] = 999
    print(a)  # [[1, 2], [3, 4]] ✅ 完全獨立
    
    '''使用 deepcopy 可以確保所有內部物件都被獨立複製'''
    ```

    ::: spoiler **Python `copy`(拷貝) 比較表**
    <br/>

    | 概念   | Python 賦值 | Python 淺拷貝 | Python 深拷貝 |
    |-|-|-|-|
    | 外層物件 | 共用 | 複製 | 複製 | 複製（bitwise） | 複製（new 出新記憶體） |
    | 內層物件 | 共用 | 共用 | 複製 | 共用指標 | 複製記憶體內容 |
    | 使用場景 | 快速參考 | 效率佳但要小心 | 完全獨立資料 | 預設行為 | 防止共用造成錯誤 |
    :::


    c. 🧪 小測驗
    ```python
    x = [1, 2, 3]
    y = x
    z = x.copy()

    y[0] = 99
    z[1] = 77

    print(x)  # ?
    print(y)  # ?
    print(z)  # ?
    ```

<br/>

## 小結

- Python 是 **動態型別語言**，不需事先宣告變數型別，會根據賦值自動判斷。
- 常見的資料型態可分為五大類：
  1. **Numeric 數值型別**：`int`、`float`、`complex`
  2. **Boolean 布林型別**：`True` / `False`，常用於邏輯判斷
  3. **Sequence 序列型別**：`str`、`list`、`tuple`（具順序，可用索引存取）
  4. **Set 集合型別**：`set`，無順序、不重複
  5. **Dictionary 字典型別**：`dict`，以鍵值對（key-value）儲存資料

- **變數命名**需遵循規範，並具描述性，便於閱讀與維護。
- 使用 `type()` 可以隨時檢查變數的資料型態。
- 變數儲存的是「**指向資料的參考（reference）**」，而非值的複製，尤其在處理 list、dict 時要注意「共享 vs 拷貝」的差異。
- 遇到多層資料結構時可使用 `copy()` 或 `deepcopy()` 做資料複製，避免非預期的修改行為。

<br/>

:::spoiler __Relevant Resources__
[Python Variables](https://www.w3schools.com/python/python_variables.asp)
[🔁 上一節： **環境設定與標準輸入輸出**](/rirdIkdWRh6Thlx93gJ6YQ)
[🔁 下一節： **條件與流程控制 (if, for, while)**](/8IoFyK7ISEqfk4qN4PLApg)
:::