{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "<p style=\"text-align:center\">\n", " <a href=\"https://nbviewer.jupyter.org/github/twMr7/Python-Machine-Learning/blob/master/QuickStart/Python_Quick_Start.ipynb\">\n", " Open In Jupyter nbviewer\n", " <img style=\"float: center;\" src=\"https://nbviewer.jupyter.org/static/img/nav_logo.svg\" width=\"120\" />\n", " </a>\n", "</p>" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[](https://colab.research.google.com/github/twMr7/Python-Machine-Learning/blob/master/QuickStart/Python_Quick_Start.ipynb)\n", "\n", "# Python Quick Start\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "37f0jbwARQeJ" }, "outputs": [], "source": [ "\"\"\"\n", "如果你已經裝好必要的Python套件環境的話,這份notebook可以在自己的電腦上執行。不然,可以使用Google的Colab。\n", "\n", "若在Colab上開啟,請執行以下步驟:\n", "1. 按右上角的【連線】,啟動雲端的Linux虛擬機器環境。\n", "2. 執行這一格的程式碼,以安裝必要的套件。\n", "\"\"\"\n", "# 目前所有必要的套件在Colab上都有,這一格可以不用執行\n", "!python --version\n", "!pip list\n", "\n", "# 日後若發現缺了某個套件,可以用 !pip install <套件名稱> 安裝" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 資料型別 Data Types\n", "\n", "- 文件連結: [Built-in Types](https://docs.python.org/3/library/stdtypes.html)\n", "\n", "對 Python 來說,程式碼裡操作的所有東西都是物件(Object),所以比較正確的來說,以下介紹的是初學 Python 應該要知道的幾種常用物件型別(Object types): **數值**(Number)、**序列**(Sequence)、**對應集**(Mapping)、以及**檔案**和**None**等物件。 有的物件型別的資料內容可以就地變更(Mutable),有的不能就地變更(Immutable)。\n", "\n", "| 物件類型 | Mutability | 內建物件型別 |\n", "|-----------|--------------|-----------------------------------------|\n", "| 數值 | *immutable* | **`int`, `bool`, `float`, `complex`** |\n", "| 序列 | *mutable* | **`list`** |\n", "| 序列 | *immutable* | **`str`, `tuple`** |\n", "| 對應集 | *mutable* | **`dict`** |\n", "| 檔案/串流 | n/a | **`file`** |\n", "| NoneType | n/a | **`None`** |\n", "\n", "- 內建函式 `type()` 可以用來檢驗物件的型態。\n", "- 內建函式 `print()` 可以用來把資料內容用文字方式顯示。\n" ] }, { "cell_type": "markdown", "metadata": { "id": "Aq8R-34Bh550" }, "source": [ "\n", "### § 數值 Numbers\n", "\n", "- 文件連結: [Numeric Types — int, float, complex](https://docs.python.org/3/library/stdtypes.html#numeric-types-int-float-complex) \n", "\n", "| 型別 | 範例 |\n", "|-------------|-------------------------------------------------------|\n", "| **int** | `1234`, `−24` ,`0`, `0x9ff`(十六進位), `0b1111`(二進位)|\n", "| **bool** | `True`(1), `False` (0) |\n", "| **float** | `1.23`, `3.14e-10`, `4E210`, `4.0e+210`, `1.`, `.1` |\n", "| **complex** | `3+4j`, `3.0+4.0j`, `3J` |" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "### § 字串 — `str`\n", "\n", "- 文件連結: [Text Sequence Type — str](https://docs.python.org/3/library/stdtypes.html#text-sequence-type-str)\n", "\n", "`str`字串是以字元為元素的序列資料結構,字串的語法使用單引號或雙引號包起來,一樣的引號要成對使用。\n", "\n", "元素內容是按照儲存順序的 index 存取,語法為 **`[ index ]`**。 如果按照由前往後的順序,**第一個元素 index 是0**,依次往後遞增; 如果反過來由後往前存取,**最後一個元素 index 可以用-1**,依次向前遞減。\n", "\n", "| 字串範例 | 說明 |\n", "|------------------------------|-----------------------------------------------|\n", "| `''` | 空字串 |\n", "| `\"Python's\"`, `'Python\"s'` | 字串用單引號或雙引號包起來 |\n", "| `'Python\\'s\\n'` | 特殊字元前面要加反斜線 `\\` |\n", "| `r'c:\\Users\\name'` | 引號前置碼`r`保留字串呈現的原貌(raw string) |\n", "| `\"This\" \"is\" \"concatenated\"` | 相鄰的字串會自動被串接起來 |\n", "\n", "- 內建函式 `str()` 用來建構新字串,或將物件轉成字串。\n", "- 內建函式 `len()` 可以用來回傳字串的長度。\n", "\n", "字串類別本身有很多專屬的方法,以下是幾個常用的方法:\n", "- `format()` 用來格式化字串。\n", "- `count()` 計算某個子字串出現幾次。\n", "- `find()` 找出子字串出現的位置。\n", "- `lower()` 返回全部是小寫的複本。\n", "- `upper()` 返回全部是大寫的複本。\n", "- `replace()` 將子字串全部替換成指定的字串。\n", "- `split()` 將字串按照指定的分隔符號切割。\n", "- `strip()` 移除字串前後的空白字元。\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "### § 序列容器 — `list`\n", "\n", "- 文件連結: [Sequence Types — list, tuple, range](https://docs.python.org/3/library/stdtypes.html#sequence-types-list-tuple-range)\n", "\n", "`list` 是存放序列性資料的結構。語法使用逗號 `,` 分隔資料元素,用中括號(square brackets)`[` `]` 成對包住所有元素。`list`可以是巢狀多維度的,同一個`list`中也可以存放異質類型資料,不過一般使用情境還是以同類型的資料較適合。\n", "\n", "元素內容是按照儲存順序的 index 存取,語法為 **`[ index ]`**。 如果按照由前往後的順序,**第一個元素 index 是0**,依次往後遞增; 如果反過來由後往前存取,**最後一個元素 index 可以用-1**,依次向前遞減。 \n", "\n", "| List 範例 | 說明 |\n", "|------------------------------------|-----------------------------------------------|\n", "| `[]` | 空的 list |\n", "| `[5, 6, 7, 8]` | 四個數字元素的 list |\n", "| `['code', [42, 3.1415], 1.23, {}]` | 巢狀、異質的 list |\n", "\n", "- 內建函式 `list()` 可以用來建構一個新的`list`物件。\n", "- 內建函式 `len()` 可以用來回傳容器裡的元素個數。\n", "- 內建函式 `min()` 可以用來回傳容器中最小的元素。\n", "- 內建函式 `max()` 可以用來回傳容器中最大的元素。\n", "\n", "`list` 是序列容器,可以使用序列容器的共通方法(參閱官方文件 [Common Sequence Operations](https://docs.python.org/3/library/stdtypes.html#common-sequence-operations))。 此外,`list` 在建立後,元素內容**可以**就地變更(mutable),標準函式庫另外還有提供可以就地變更的方法,請參閱官方文件 [Mutable Sequence Types](https://docs.python.org/3/library/stdtypes.html#typesseq-mutable),以下是幾個常用的`list`類別方法:\n", "- `append()` 追加一個元素在容器後面。\n", "- `extend()` 追加一系列的元素在容器後面。\n", "- `del L[m:n]` 刪除範圍內的元素,與 `L[m:n] = []` 相同。\n", "- `copy()` 產生一份複製,與 `L[:]` 相同。\n", "- `clear()` 移除所有的元素,與 `del L[:]` 相同。\n", "- `insert()` 插入元素到某個位置。\n", "- `remove()` 移除第一個出現的指定元素值。\n", "- `pop()` 回傳某個位置的元素值,並從容器中移除。\n", "- `sort()` 對元素就地排序。\n", "- `reverse()` 就地反轉元素順序。\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "### § 序列容器 — `tuple`\n", "\n", "- 文件連結: [Sequence Types — list, tuple, range](https://docs.python.org/3/library/stdtypes.html#sequence-types-list-tuple-range)\n", "\n", "`tuple`也是存放序列性資料的結構。語法使用逗號 `,` 分隔資料元素,用小括號(parentheses)`(` `)` 成對包住所有元素,但括號可以省略。 `tuple`可以是巢狀多維度的,同一個`tuple`中也可以存放異質類型資料,通常使用在函式參數的傳遞與回傳。\n", "\n", "元素內容是按照儲存順序的 index 存取,語法為 **`[ index ]`**。 如果按照由前往後的順序,**第一個元素 index 是0**,依次往後遞增; 如果反過來由後往前存取,**最後一個元素 index 可以用-1**,依次向前遞減。\n", "\n", "| tuple 範例 | 說明 |\n", "|------------------------------------|-----------------------------------------------|\n", "| `()` | 空的 tuple |\n", "| `('code',)` | 單一元素的 tuple |\n", "| `(5, 6, 7, 8)` | 四個數字元素的 tuple |\n", "| `('code', (42, 3.1415), 1.23, {})` | 巢狀、異質的 tuple |\n", "| `'code', 42, 3.1415, 1.23` | 括號可以省略 |\n", "\n", "- 內建函式 `tuple()` 可以用來建構一個新的`tuple`物件。\n", "- 內建函式 `len()` 可以用來回傳容器裡的元素個數。\n", "- 內建函式 `min()` 可以用來回傳容器中最小的元素。\n", "- 內建函式 `max()` 可以用來回傳容器中最大的元素。\n", "\n", "`tuple` 在建立後,元素內容**不可以**就地變更(immutable)。 `tuple` 是序列容器,所以一般序列容器的共同方法都可以用,參閱官方文件 [Common Sequence Operations](https://docs.python.org/3/library/stdtypes.html#common-sequence-operations)。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "### § 字典容器 — `dict`\n", "\n", "- 文件連結: [Mapping Types — dict](https://docs.python.org/3/library/stdtypes.html#mapping-types-dict)\n", "\n", "`dict`是非序列式的資料結構,元素內容的儲存是成對的 key 和對應的 value。語法使用冒號組成 key 和 value 對應組 `key:value`,以逗號 `,` 分隔對應組元素,用大括號(curly braces)`{` `}` 成對包住所有元素。 同一個 `dict` 中的 `value` 可以存放異質類型資料。`dict` 也可以是巢狀的,也就是 `value` 中含有另外一個 `dict` 類型的資料。\n", "\n", "元素內容必須用 `key` 來存取,語法為 **`[ key ]`**。\n", "\n", "| dict 範例 | 說明 |\n", "|------------------------------------|-----------------------------------------------|\n", "| `{}` | 空的 dict |\n", "| `{'alpha': 2, 'beta': 3}` | 兩個元素的 dict |\n", "| `{ 'parameter': { 42: 1.5, 'angle': 30 }, 'date': ['2018-06-08'] }` | 巢狀、異質的 dict |\n", "| `dict([['a', 1], ['b', 2], ['c', 3]])` | 由list中建構一個新的dict物件 |\n", "\n", "- 內建函式 `dict()` 可以用來從現有物件的資料實體中生成一個新的tuple。\n", "- 內建函式 `len()` 可以用來回傳容器裡key-value對的個數。\n", "\n", "`dict` 在建立後,元素的 `value` **可以**就地變更(mutable),`key` 不可以就地變更(immutable),也不允許 mutable 的物件類型當 `key`。 `dict` 類別常用的方法:\n", "- `clear()` 清除所有容器內的內容。\n", "- `copy()` 複製。\n", "- `get()` 回傳某個 key 的對應 value,沒有的話就回傳預設值。\n", "- `pop()` 回傳並移除某個 key 的對應 value,沒有的話就回傳預設值。\n", "- `items()` 回傳可迭代的所有 (key, value) view。\n", "- `keys()` 回傳可迭代的所有 key 的 view。\n", "- `values()` 回傳可迭代的所有 value 的 view。\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "## 操作運算子 Operators\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "### § 數值與算術運算 Numeric and Arithmetic Operations\n", "\n", "| 算數的操作 | 說明 |\n", "|--------------------|--------------|\n", "| **X + Y, X - Y** | 加法,減法 |\n", "| **X \\* Y, X / Y** | 乘法,除法 |\n", "| **X // Y, X % Y** | 取商,取餘數 |\n", "| **X\\*\\*Y** | 次方 |" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "### § 布林運算 Boolean Operations\n", "\n", "| 布林的運算 | 程式解譯邏輯 | 說明 |\n", "|-------------|-------------------------------------|--------------------------------------|\n", "| **X or Y** | 假如X為False則Y,否則X。 | 其中一個為True就是True,否則是False |\n", "| **X and Y** | 假如X為False則X,否則Y。 | 兩個都為True才是True,否則是False |\n", "| **not X** | 假如X為False則True,否則False。 | 反轉 |\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "### § 比較運算 Comparisons Operations\n", "\n", "| 比較的運算 | 說明 |\n", "|----------------|--------------|\n", "| **X < Y** | 小於 |\n", "| **X <= Y** | 小於或等於 |\n", "| **X > Y** | 大於 |\n", "| **X >= Y** | 大於或等於 |\n", "| **X == Y** | 等於 |\n", "| **X != Y** | 不等於 |\n", "| **X is Y** | 是否相同物件 |\n", "| **X is not Y** | 是否不同物件 |\n", "\n", "- 對於容器物件的直接比較, ***“大於”*** 和 ***“小於”*** 的概念可能時常沒什麼太大意義, ***“等於”*** 或 ***“不等於”*** 則時常用到。\n", "- 物件在電腦裡都有一個對應的記憶體存放位址,可以用 `id()` 取得。 當 `is` 比較兩個物件是否相同時,實際比較的就是兩個物件是否有相同 `id()`。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "## 變數與物件 Variable and Object\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### § 指派述句 Assignment Statements\n", "\n", "Python是**動態型別(dynamic type)**的程式語言。為資料或物件指定變數名字時,程式碼中不需要明確宣告變數的型別。例如:當指定 `a = 3` 時,Python 會根據你的要求做這些步驟:\n", "1. 判斷 3 屬於 int 型別。\n", "2. 建立一個 3 的 int 物件。\n", "3. 建立一個名字叫做 a 的變數(如果原本 a 不存在)。\n", "4. 把變數 a 參考到物件 3 的關係連結起來。\n", "\n", "是**物件擁有型別**,不是變數。變數只是個指向參考物件的名字而已。" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "<class 'int'>\n", "<class 'str'>\n", "<class 'list'>\n" ] } ], "source": [ "a = 3\n", "print(type(a))\n", "\n", "# 改變 a 參考的物件\n", "a = 'a string'\n", "print(type(a))\n", "\n", "# 再一次改變 a 參考的物件\n", "a = [5, 6, 7]\n", "print(type(a))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "### § 物件參考 Object Reference\n", "\n", "兩個變數可以共享物件的參考。當變數 a 和 b 參考至同一個物件:\n", "- 對於可以就地變更元素內容的容器而言,修改 b 的元素內容,因為是同一份物件,a 的元素內容跟著變。\n", "- 若指定一個新的物件給其中一個變數,就算內容一模一樣,兩變數結果會是參考至不同物件。\n" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\"b == a\" True\n", "\"b is a\" True\n" ] } ], "source": [ "a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n", "b = a\n", "\n", "# \"==\"比較內容,\"is\"判斷是否為同一個物件參考,應該都會是 True\n", "print('\"b == a\"', b == a)\n", "print('\"b is a\"', b is a)" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\"b == a\" True\n", "\"b is a\" True\n" ] } ], "source": [ "# a 和 b 參考至同一物件\n", "a = b = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n", "\n", "# 修改一個的元素內容,另一個會跟著變\n", "b[-1] = 11\n", "print('\"b == a\"', b == a)\n", "print('\"b is a\"', b is a)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\"b == a\" True\n", "\"b is a\" False\n" ] } ], "source": [ "# a 和 b 參考至同一物件\n", "a = b = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n", "\n", "# 指定相同內容的新物件給 b,兩變數的參考物件變成不同\n", "b = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n", "print('\"b == a\"', b == a)\n", "print('\"b is a\"', b is a)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\"b == a\" True\n", "\"b is a\" False\n" ] } ], "source": [ "# a 和 b 參考至同一物件\n", "a = b = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n", "\n", "# 同樣是指定了新物件 - list經過索引返回的片段是新的物件\n", "b = a[:]\n", "print('\"b == a\"', b == a)\n", "print('\"b is a\"', b is a)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "## 序列容器的操作 Sequence Operations\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "### § 基本索引規則 Indexing Rules\n", "\n", "- 在序列容器變數後,使用中括號內置索引序號,如:`S[3]`。\n", "- 序列第一個元素的索引序號為 `0`,往後面依次遞增。如:`S[0]`, `S[1]`, ..., `S[len(S) - 1]`。\n", "- 序列最後一個元素的索引序號為 `-1`,往前面依次遞減。如:`S[-1]`, `S[-2]`, ..., `S[-len(S)]`。\n", "- 可以使用的索引序號不能超過物件的元素個數減1。如:`S[len(S)]` Python會出現錯誤訊息。\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "### § 進階索引規則 Slicing Rules\n", "\n", "由序列容器中取出片段成為一個新的序列容器物件,可以取得的片段範圍僅限於合法的索引範圍。若指定的片段超過範圍,所產生的新序列容器只會包含合法範圍內的片段,Python不會發出錯誤訊息。片段範圍的指定一樣使用中括號,語法如下:\n", "\n", "<p style=\"text-align: center;font-weight:bold\">\n", " [ 起始序號 : 結束序號 : 遞增(減)量 ]\n", "</p>\n", "\n", "- 注意索引結果的元素,不包含結束序號的那個元素;也就是說 `[start : end]` 取的是 $[start, end)$ 的區間。\n", "\n", "| Slicing 的操作 | 說明 |\n", "|----------------|----------------------------------------------|\n", "| `S[1:3]` | 取元素範圍序號 1 到 2 |\n", "| `S[1:]` | 取元素範圍序號 1 到最後一個 |\n", "| `S[:-1]` | 取元素範圍第一個到最後一個的前一個 |\n", "| `S[:]` | 取所有範圍的元素 |\n", "| `S[2::3]` | 元素範圍序號 2 到最後一個,每遞增 3 個序號取 |\n", "| `S[::2]` | 所有元素的範圍內,從頭到尾每隔一個序號取 |\n", "| `S[::-1]` | 反向取所有範圍的元素 |\n", "| `S[-2:0:-1]` | 所有範圍的元素去頭尾,反向取 |\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "### § 成員操作 Membership Operations\n", "\n", "| 成員的操作 | 說明 |\n", "|------------------------|------------------------------------------------------------------|\n", "| `x in S` | S 的成員裡有 x(只要值相同就算),結果為 `True` 或 `False` |\n", "| `x not in S` | S 的成員裡沒有 x ,結果為 `True` 或 `False` |\n", "| `for x in S:` | (迴圈)列舉 S 裡的成員到 x |\n" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 2, 3, 4, 5, 6, 7, 8, 9]\n" ] } ], "source": [ "# 用 range() 來幫忙產生整數列\n", "L = list(range(1, 10))\n", "print(L)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 2, 3, 4, 5, 6, 7, 8]" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 取開始到倒數第二個的區間\n", "L[:-1]" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[9, 8, 7, 6, 5, 4, 3, 2, 1]" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 反向取所有元素\n", "L[::-1]" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 7, 6, 5, 4, 3, 2, 1]" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 兩個 list 相加結果就是做串接\n", "L[:-1] + L[::-1]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "## 迴圈及流程控制 Loops and Control flow\n", "\n", "對於一般陳述句,Python 會一行一行往下執行,直到碰到改變流程的陳述句:\n", "\n", "+ `if-elif-else`: 條件陳述式,選擇性執行。\n", "+ `while`: 條件式迴圈,迭代執行。\n", "+ `for`: 序列式迴圈,迭代執行。\n", "\n", "條件或迴圈的語法,共同點是都在測試某個條件後,符合條件才會執行接續的區塊陳述。 Python 程式的語法中,區塊的程式碼使用 ***space*** 或 ***tab*** 縮排的層次來區隔不同執行條件的陳述句。\n", "\n", "+ `pass`: 佔位述句。\n", "+ `break`: 中斷。\n", "+ `continue`: 繼續。\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "### § if-elif-else 條件陳述式\n", "\n", "`if-elif-else` 條件陳述式由一個 `if` 邏輯測試條件,中間可有可無的 `elif` 測試條件,以及最後也是可有可無的 `else` 條件所組成。 每個條件都有對應的陳述式區塊,在條件測試為 True 時會被執行。 一般的形式像:\n", "```\n", "if test1:\n", " statements1\n", "elif test2:\n", " statements2\n", "else:\n", " statements3\n", "```\n", "\n", "簡單的 if-else 指派陳述如:\n", "```\n", "if test:\n", " x = a\n", "else:\n", " x = b\n", "```\n", "可以簡化成一行**三元運算**的陳述句:\n", "```\n", "x = a if test else b\n", "```\n" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "neither good nor bad, x is excellent\n" ] } ], "source": [ "a, b = 'good', 'bad'\n", "\n", "# 試著改變 x = 'good', 或 x = 'bad' 看看條件測試的結果\n", "x = 'excellent'\n", "#x = 'good'\n", "#x = 'bad'\n", "\n", "if x == a:\n", " print('x is also good')\n", "elif x == b:\n", " print('x is bad')\n", "else:\n", " print('neither good nor bad, x is {}'.format(x))" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'good'" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 三元運算陳述句\n", "a if x != 'bad' else b" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### § while 條件式迴圈\n", "\n", "`while` 迴圈包含了一個標頭的邏輯條件測試式,一個或多個縮排的區塊陳述式。\n", "\n", "```\n", "while test:\n", " statements\n", "```\n" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "excellent\n" ] } ], "source": [ "# 一個一個字元複製直到字串完全相等\n", "x = 'excellent'\n", "c = ''\n", "while c != x:\n", " c += x[len(c)]\n", "\n", "print(c)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "excellent\n", "excellen\n", "excelle\n", "excell\n", "excel\n", "exce\n", "exc\n", "ex\n", "e\n", "c = 0\n" ] } ], "source": [ "# 註: Python 的空字串會被視為是其他字串的子字串\n", "while c in x:\n", " print(c)\n", " if len(c) > 1:\n", " c = c[:-1]\n", " elif len(c) == 1:\n", " # 試看看 c = '0' 和 c = '' 的結果有甚麼不同?\n", " c = '0'\n", " else:\n", " break\n", "\n", "print('c =', c)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "### § for 序列式迴圈\n", "\n", "`for` 迴圈是一個通用的迭代器(iterator),可以用來走訪任何***序列容器的元素***或***可迭代(iterable)物件***。 `for` 迴圈區塊標頭從要走訪的 iterable_object 中循序指派內容物參考到 item,然後針對每個 item 重複執行區塊中的陳述句。\n", "\n", "```\n", "for item in iterable_object:\n", " statements\n", "```\n" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "e\n", "x\n", "c\n", "e\n", "l\n", "l\n", "e\n", "n\n", "t\n" ] } ], "source": [ "# 變數 c 不須事先宣告,若先前已經有值也不影響 for 迴圈的執行\n", "for c in x:\n", " print(c)" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "e\n", "x\n", "c\n", "e\n", "l\n", "l\n", "e\n", "n\n", "t\n" ] } ], "source": [ "for c in x:\n", " # 試看看在 '0123456789' 字串中加入任意一個 'e', 'x', 'c', 'l', 'n', 't' 的字元,結果有甚麼不同?\n", " if c not in '0123456789':\n", " print(c)\n", " else:\n", " break" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "### § pass 佔位述句\n", "\n", "什麼事都沒作,通常只是為了暫時滿足語法規則,用來佔個位置的述句。 \n", "\n", "```\n", "while True:\n", " pass\n", "```" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "# 沒作甚麼事,單純占用 CPU 時間的迴圈\n", "for i in range(2**25):\n", " pass" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "### § break 中斷\n", "\n", "跳離最近的 `for` 或 `while` 迴圈。\n" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0\n", "1\n", "2\n", "3\n", "4\n", "5\n" ] } ], "source": [ "for i in range(10):\n", " if i > 5: break\n", " print(i)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "### § continue 繼續\n", "\n", "在迴圈中出現時,忽略以下所有述句,回到迴圈標頭繼續下一輪迴圈。\n" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "5\n", "6\n", "7\n", "8\n", "9\n" ] } ], "source": [ "n = list(range(10))\n", "for i in n:\n", " if i < 5: continue\n", " print(i)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "## Comprehension 語法\n", "\n", "- 操作 `list` 和 `dict` 容器時,Python 提供了強大的功能性語法,分別稱為 [***List Comprehensions***](https://www.python.org/dev/peps/pep-0202/) 與 [***Dict Comprehensions***](https://www.python.org/dev/peps/pep-0274/)。\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "### § List Comprehensions\n", "\n", "對於序列容器或可迭代物件 S 進行操作,並生成一個新的 `list` 物件。\n", "\n", "| 成員的操作 | 說明 |\n", "|-----------------------------------|-------------------------------------------------------------------|\n", "| `[運算表示句 for x in S]` | 針對每個 S 的成員 x 做運算,運算結果生成新的 list 物件 |\n", "| `[運算表示句 for x in S if 條件]` | 針對每個***符合條件***的成員 x 做運算,運算結果生成新的 list 物件 |\n", "\n", "List comprehension 語法結構可組成相當豐富的條件式迭代運算\n", "\n", "```\n", "[運算表示句 for x1 in S1 if 條件1\n", " for x2 in S2 if 條件2 ...\n", " for xN in SN if 條件N]\n", "```\n" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[11, 12, 13, 14, 15]\n" ] } ], "source": [ "L = [1, 2, 3, 4, 5]\n", "\n", "# 使用 List Comprehension 生成新的 List 物件\n", "L = [x + 10 for x in L]\n", "print(L)" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0, 4, 8, 12, 16]" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 條件式挑選部份成員作處理\n", "[n*2 for n in range(10) if n % 2 == 0]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "### § Dict Comprehensions\n", "\n", "對於可拆解出成對的 (key, value) 的序列容器或可迭代物件 S 進行操作,並生成一個新的 `dict` 物件。\n", "\n", "| 成員的操作 | 說明 |\n", "|--------------------------------------------|---------------------------------------------------------------|\n", "| `{key:value for (key,value) in S}` | 針對每個 S 的成員 x 做運算,運算結果生成新的 dict 物件 |\n", "| `{key:value for (key,value) in S if 條件}` | 針對每個***符合條件***的成員 x 做運算,運算結果生成新的 dict 物件 |\n", "\n", "Dict comprehension 語法結構也可組成相當豐富的條件式迭代運算,但需注意`dict`容器的 *key* 不能重複,若重複指定不同 value 給同一個 key,結果對應的 value 會是最後指定的值。\n", "\n", "```\n", "{key:value運算表示句 for x1 in S1 if 條件1\n", " for x2 in S2 if 條件2 ...\n", " for xN in SN if 條件N}\n", "```" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'a': 97, 'b': 98, 'c': 99}" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 可迭代物件生成 dict 物件\n", "{x: ord(x) for x in 'abc'}" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'0': 0, '2': 4, '4': 16, '6': 36, '8': 64}" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 條件式挑選部份成員作處理\n", "{str(x): x ** 2 for x in range(10) if x % 2 == 0}" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'a': 1, 'b': 2, 'c': 3}" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 需要兩組序列進行兩兩配對的操作時,可以使用內建函式 zip() 來幫忙\n", "{k: v for (k, v) in zip(['a', 'b', 'c'], [1, 2, 3])}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "## 函式 Functions\n", "\n", "- Python 標準函示庫包含了一些常用的[內建函式](https://docs.python.org/3/library/functions.html)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### § def 函式定義\n", "\n", "函式以 `def` 關鍵字及指定的函式名字開始,後面使用小括號接著函式運算需要的所有參數。 區塊陳述包含函式所需的運算,運算結果的值使用 `return` 述句返回,若未明確指定,預設返回值為 `None`。\n", "\n", "```\n", "def name(arg_name1,..., arg_nameN=value):\n", " statements\n", " return value\n", "```\n", "\n", "| 可用參數定義格式 | 格式說明 |\n", "|--------------------|-------------------------------------------|\n", "| `arg_name1` | 一般參數,以位置或名字匹配 |\n", "| `arg_nameN=value` | 同一般參數,明確指定預設值 |\n", "\n", "\n", "**函式呼叫**\n", "\n", "```\n", "name(arg_value1,... arg_nameN=value)\n", "```\n", "\n", "| 可用參數定義格式 | 格式說明 |\n", "|---------------------|------------------------------------------------|\n", "| `arg_value1` | 以位置匹配傳遞參數 |\n", "| `arg_name_N=value` | 以名字匹配傳遞參數 |\n" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n", "1\n" ] } ], "source": [ "# 定義一個函式 Add(): 印出輸入參數相加的結果\n", "def Add(a, b, c):\n", " print(a + b + c)\n", "\n", "# 函式呼叫與參數傳遞\n", "Add(2, 3, -4)\n", "\n", "# 以位置及名字匹配方式傳遞參數\n", "Add(2, c=-4, b=3)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "### § 參數傳遞的基本認識\n", "\n", "1. 參數的傳遞,是**物件的參考**複製給了函式的 local 變數名字; 意即函式***參數所指向物件與呼叫端是同一物件***。\n", "2. 在函式內,重新指派新的物件參考給參數變數名字,不會影響呼叫端。\n", "3. 如果參數物件是可就地變更的類別,在函式內異動物件內容,呼叫端也會跟着改變。\n", "\n", "在設計程式時,建議遵循以下原則:\n", "1. 在函式中,避免更改參數物件的元素內容。\n", "2. 如果有需要回傳運算結果,請利用 `return` 來回傳,讓呼叫端來決定是否覆蓋原物件內容。\n" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "b = 5 id = 140708456839104\n", "a = 5 id = 140708456839104\n", "a = 9 id = 140708456839232\n", "b = 5 id = 140708456839104\n" ] } ], "source": [ "# 指派新物件不影響呼叫端\n", "def f(a):\n", " # 一開始 a 與呼叫端的 b 參考同一物件\n", " print('a =', a, 'id =', id(a))\n", " # 指派新的 int 物件\n", " a = 9\n", " # 現在 a 參考到新物件\n", " print('a =', a, 'id =', id(a))\n", "\n", "b = 5\n", "# before function call\n", "print('b =', b, 'id =', id(b))\n", "\n", "f(b)\n", "\n", "# after function called\n", "print('b =', b, 'id =', id(b))" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "x = [2, 3] id = 2427060925824\n", "y = [4, 5, 6] id = 2427061789376\n", "L1 = [2, 3] id = 2427060925824\n", "L1 = [7, 8, 9] id = 2427062155904\n", "L2 = [4, 5, 6] id = 2427061789376\n", "L2 = ['changed', 5, 6] id = 2427061789376\n", "x = [2, 3] id = 2427060925824\n", "y = ['changed', 5, 6] id = 2427061789376\n" ] } ], "source": [ "# 可就地變更的類別,兩邊內容是同一份\n", "def f_list_args(L1, L2):\n", " print('L1 =', L1, 'id =', id(L1))\n", " # 指派新的 list 物件\n", " L1 = list(range(7, 10))\n", " print('L1 =', L1, 'id =', id(L1))\n", " \n", " print('L2 =', L2, 'id =', id(L2))\n", " # 不建議在函式中直接更改參數物件的元素內容。\n", " L2[0] = 'changed'\n", " print('L2 =', L2, 'id =', id(L2))\n", "\n", "\n", "x = [2, 3]\n", "y = [4, 5, 6]\n", "\n", "# before function call\n", "print('x =', x, 'id =', id(x))\n", "print('y =', y, 'id =', id(y))\n", "\n", "f_list_args(x, y)\n", "\n", "# after function called\n", "print('x =', x, 'id =', id(x))\n", "print('y =', y, 'id =', id(y))\n" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "vec = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] id = 2427061788864\n", "vec = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] id = 2427061772544\n" ] } ], "source": [ "# 有需要回傳運算結果就用 return,讓呼叫端自己決定覆蓋原物件內容。\n", "def min_max_scaler(vec_in):\n", " min_v = min(vec_in)\n", " max_v = max(vec_in)\n", " interval = max_v - min_v\n", " vec_out = [(float(v) - min_v) / interval for v in vec_in]\n", " return vec_out, interval\n", "\n", "vec = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]\n", "\n", "# before function call\n", "print('vec =', vec, 'id =', id(vec))\n", "\n", "vec, _ = min_max_scaler(vec)\n", "\n", "# after function called\n", "print('vec =', vec, 'id =', id(vec))" ] } ], "metadata": { "colab": { "authorship_tag": "ABX9TyOuIYEocvTI/XCQlqS6NQqx", "collapsed_sections": [], "name": "Python Quick Start.ipynb", "provenance": [] }, "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.5" } }, "nbformat": 4, "nbformat_minor": 1 }