{ "cells": [ { "cell_type": "markdown", "metadata": { "id": "kosrKbvbbD4c" }, "source": [ "# 資料容器 - Containers" ] }, { "cell_type": "markdown", "metadata": { "id": "VmkAseJJx24c" }, "source": [ "本章節內容大綱\n", "* [串列 List](#List)\n", "* [元組 Tuple](#Tuple)\n", "* [集合 Set](#Set)\n", "* [字典 Dictionary](#Dictionary)" ] }, { "cell_type": "markdown", "metadata": { "id": "TZ5zpvRix24d" }, "source": [ "## List" ] }, { "cell_type": "markdown", "metadata": { "id": "hlUrTP86x24f" }, "source": [ "### 如何宣告一個 List\n", "list 的宣告使用中括號 [],或是 list(),後者可將其他型態的 Container (例如 Tuple)資料轉為 list,所以一般宣告建議使用中括號就好,以跟型態轉換做出區隔。" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "Rrn-MqzZx24f" }, "outputs": [], "source": [ "# 宣告空的 list\n", "emptyList1 = []\n", "emptyList2 = list()\n", "\n", "print(emptyList1)\n", "print(emptyList2)" ] }, { "cell_type": "markdown", "metadata": { "id": "puut0Fcsx24t" }, "source": [ "一個 list 的乘載內容不限於單一型別,可以將數字、字串、布林甚至是另一整個 list 放在同一個 list 裡面,使用上非常地自由。" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "T5gkvTFKx24w" }, "outputs": [], "source": [ "# list 中可以放入各種不同型別的變數\n", "complexList = [1, 2.3, 4 + 5j, 'five']\n", "\n", "print(complexList)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "zh2Ifa31x243" }, "outputs": [], "source": [ "# 甚至可以放入另一整個 list 作為其中一筆資料\n", "nestedList = [0, [11, 12], 2, [30, 31, 32], 4]\n", "\n", "print(nestedList)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "kbpSogZUx25M" }, "outputs": [], "source": [ "L = [3, 4, 5]\n", "print(L)\n", "\n", "# 在 list 最後面新增一筆資料,使用 append()\n", "L.append(6)\n", "print(L)\n", "\n", "# 在 list 最後面新增多筆資料,使用 + 以及另外多筆資料 (包成 list)\n", "L = L + [7, [80, 81], 9, 10]\n", "print(L)\n", "\n", "# 在 list 最前面插入多筆資料\n", "L = [0, [10, 11], 2] + L\n", "print(L)\n", "\n", "# 把 list 重複兩次\n", "L = L * 2\n", "print(L)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "XQn6CB-Dx25T" }, "outputs": [], "source": [ "L = [10, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]\n", "print(L)\n", "\n", "# 使用 remove() 移除目前 list 中希望移除的值,注意如果希望移除的值出現了很多次, remove 只會移除前面數來第一個。\n", "L.remove(10)\n", "print(L)\n", "\n", "# 使用 pop() 移除目前 list 中某個 index 的資料。\n", "L.pop(3)\n", "print(L)\n", "\n", "# 使用 clear() 移除 list 中所有資料\n", "L.clear()\n", "print(L)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "5sH4DEHSx25Y" }, "outputs": [], "source": [ "L = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]\n", "print(L)\n", "\n", "# 使用 len() 查詢目前 list總長度\n", "print(len(L))\n", "\n", "# 使用 index() 來尋找欲求資料在 list 中的位置\n", "print(L.index(6))\n", "\n", "L = [1, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6]\n", "\n", "# 使用 count() 來計算欲求資料在 list 中出現了幾次\n", "print(L.count(5))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "s8cqZL1sx25l" }, "outputs": [], "source": [ "L = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n", "print(L)\n", "\n", "'''\n", "正 index: 由左至右,從 0 開始\n", "負 index: 由右至左,從 -1 開始\n", "'''\n", "\n", "# 取得 list 中 index 為 3 的資料\n", "print(L[3])\n", "# 取得 list 中 index 由 3 至 8(不含) 的資料\n", "print(L[3:8])\n", "# 取得 list 中 index 由 3 至 8(不含),並且每次往右兩個取,的資料\n", "print(L[3:8:2])\n", "# 取得 list 中 index 由頭至 8(不含) 的資料\n", "print(L[:8])\n", "# 取得 list 中 index 由 3 至最後的資料\n", "print(L[3:])\n", "\n", "# 取得 list 中 index 由右至左數第 1 至第 8 個,並且每次往左兩個取,的資料\n", "print(L[-1:-8:-2])" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "SDRu6kijx25p" }, "outputs": [], "source": [ "nestedList = [[11, 12], [21, 22, 23], [31, 32, 33, 34]]\n", "\n", "# 對於多重 list,使用多重 index 去取得內層的資料,例如 L[2][3]\n", "# 就是取 list 中 index 為 2 的子 list,並拿出其中 index 為 3的值。\n", "print(nestedList[2][3])" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "Z_weQNMdx25v" }, "outputs": [], "source": [ "L = [0, 1, 2, 3, 4]\n", "\n", "# 使用 insert(index, value) 在 index 處插入一筆資料,下例為在 index 為 3的地方插入一個 5\n", "L.insert(3, 5)\n", "print(L)\n", "\n", "# 使用 slicing 將 list 拆成兩半,則可以在中間插入多筆資料,下例為把 list 分成前四筆 含剩下的,並在中間插入 6 7 8 9。\n", "# L[:4] 為 [0, 1, 2, 5]\n", "# L[4:] 為 [3, 4]\n", "L = L[:4] + [6, 7, 8, 9] + L[4:]\n", "print(L)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "hs3E7rOPx250" }, "outputs": [], "source": [ "# 使用 split() 將字串自動切成 list。\n", "# 例如輸入字串為 1 2 3, split()後變為 [1, 2, 3]\n", "\n", "splitList = input().split()\n", "print(splitList)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "KV5u8Wg5bD4m" }, "outputs": [], "source": [ "Str = 'Alpha Beta Gamma Theta'\n", "splitString = Str.split()\n", "print(splitString)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "bKt_SleVx258" }, "outputs": [], "source": [ "# split() 預設以空格、換行符號、逗號、tab 做為分隔符號,若要自訂分隔符號,則可在括號內輸入指定。\n", "# 例如輸入為 192.168.0.1 這種形式時,可使用 split(\".\"),以點切分。 (分隔符號也可以是字串)\n", "\n", "ip = '192.168.0.1'\n", "splitStr = ip.split(\".\")\n", "print(splitStr)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "LJmIFQr_x26L" }, "outputs": [], "source": [ "# join() 則是和 split() 相反的功能,以某個結合符號(字串)將 list 內的東西接起來。\n", "# 例如 \".\"join([1, 2, 3]) 代表以點號將 list 接起來,則結果為 \"1.2.3\"\n", "\n", "L = ['Alpha', 'Beta', 'Gamma', 'Theta']\n", "print(\", \".join(L))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "sajTn3G5x265" }, "outputs": [], "source": [ "# 使用 sort()將 list 排序,預設是升序,如果要降序的話,需要加上 reverse = True\n", "\n", "L = [4, 6, 5, 2, 1, 3, 7, 9, 8, 0]\n", "print(L)\n", "\n", "# 升序排序\n", "L.sort()\n", "print(L)\n", "\n", "# 降序排序\n", "L.sort(reverse=True)\n", "print(L)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "VxSI0Iqxx27B" }, "outputs": [], "source": [ "L1 = ['Ben', '001', 'physics', 'english', 'calculus', 'logic design', 93]\n", "L2 = ['Jen', '002', 'programming', 88]\n", "\n", "name, Id, *courses, score = L1\n", "print(name, Id, courses, score)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "QcymCBj4bD4n" }, "outputs": [], "source": [ "name, Id, *courses, score = L2\n", "print(name, Id, courses, score)" ] }, { "cell_type": "markdown", "metadata": { "id": "unb8q-dox27Y" }, "source": [ "## Tuple\n", "\n", "和 list 很像,都是一系列的任意型別資料。但與 list 不同的是,tuple 中的資料一經宣告後,**就不可做任何異動**,所以我們可以把 tuple 視為常數的串列。" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "C8bFwtXQx27Z" }, "outputs": [], "source": [ "# 宣告空的 tuple\n", "T1 = ()\n", "T2 = tuple()\n", "\n", "print(T1)\n", "print(T2)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "MZoybAEhx27s" }, "outputs": [], "source": [ "# Tuple 和 List 是可以互相轉換的\n", "T = (1, 2, 3)\n", "L = list(T)\n", "print(L)\n", "print(T)\n", "\n", "L = [1, 2, 3]\n", "T = tuple(L)\n", "print(L)\n", "print(T)" ] }, { "cell_type": "markdown", "metadata": { "id": "jofK7Fdpx27v" }, "source": [ "## Set\n", "\n", "集合與List最大的不同是沒有順序性。" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "8kRzBnpNx27v" }, "outputs": [], "source": [ "# 宣告一個空集合\n", "S = set()\n", "print(S)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "-KfUjgObx27z" }, "outputs": [], "source": [ "# 宣告有東西的集合使用大括號 {},\n", "S1 = {1, 2, 3, 4}\n", "S2 = {3, 4, 5, 6, 6}\n", "print(S1)\n", "print(S2)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "COcvMsacx272" }, "outputs": [], "source": [ "S1 = {1, 2, 3, 4}\n", "S2 = {3, 4, 5, 6, 6}\n", "\n", "# 兩集合的交集使用 & 符號\n", "print(S1 & S2)\n", "\n", "# 兩集合的聯集使用 | 符號\n", "print(S1 | S2)\n", "\n", "# 兩集合的差集使用 - 符號\n", "print(S1 - S2)\n", "print(S2 - S1)\n", "\n", "# 兩集合的互斥集使用 ^ 符號\n", "print(S1 ^ S2)\n", "\n", "# 使用 >, <, =, >=, <=, == 判斷集合間的子集關係\n", "print(S1 <= S2)\n", "print(S1 >= S2)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "dk5EAx01x278" }, "outputs": [], "source": [ "# 集合可由 list 及 tuple 轉換而來,不過集合中的資料是沒有順序的。\n", "S = set([3, 1, 2, 4])\n", "print(S)\n", "\n", "S = set((1, 5, 2, 3))\n", "print(S)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "zvQuIIEOx27_" }, "outputs": [], "source": [ "S = {1, 2, 3, 4}\n", "\n", "# 在集合中增加一物件\n", "S.add(5)\n", "print(S)\n", "\n", "# 若要將集合與其他集合做合併,可使用 update(),兩集合重複的物件將不會重複合併。\n", "S.update((6, 7, 8))\n", "print(S)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "GJitVlD6bD4p" }, "outputs": [], "source": [ "S = {1, 2, 3}\n", "S.add(3)\n", "S" ] }, { "cell_type": "markdown", "metadata": { "id": "dBSYbbWQx29H" }, "source": [ "## Dictionary" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "RkBsesTCx29I" }, "outputs": [], "source": [ "# 宣告一個空字典,使用大括號,或是直接使用 dict()。\n", "# 這邊容易搞混的是集合與字典,因為他們一樣都是用大括號,要記得如果只宣告一個大括號的話,出來的型別會是字典!\n", "D1 = {}\n", "D2 = dict()\n", "\n", "print(type(D1))\n", "print(type(D2))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "LUvjotF_x29O" }, "outputs": [], "source": [ "# 宣告有資料的字典時,由於和集合一樣都是使用大括號,所以在資料部分的格式必須由所區隔。\n", "# 每一筆都需要有兩個任意型別的物件 (key, value),例如 'a' 和 1,並且以冒號隔開,這樣的意思是在這個字典中,\n", "# 呼叫 key('a') 會得到 value (1)。\n", "\n", "D = {'a': 1, 'b': 2, 3: 'c'}\n", "S = {1, 2, 3}\n", "\n", "print(type(D))\n", "print(type(S))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "2IXREif6bD4s" }, "outputs": [], "source": [ "print(D['a'])" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "eamdNvO6x29Z" }, "outputs": [], "source": [ "# 將 list 轉換成字典,注意 list 中每筆資料都要是一個 \"內含兩個資料的 list\"\n", "# 轉換後 每兩筆中的第一筆將會是 key,另一筆是 value。\n", "L = [[1, 'a'], [2, 'b'], [3, 'c'], [4, 'd']]\n", "\n", "D = dict(L)\n", "print(D)\n", "\n", "# 將 tuple 轉換成字典,注意 tuple 中每筆資料都要是一個 \"內含兩個資料的 tuple\"\n", "# 轉換後 每兩筆中的第一筆將會是 key,另一筆是 value。\n", "S = (('a', 1), ('b', 2), ('c', 3), ('d', 4))\n", "\n", "D = dict(S)\n", "print(D)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "T6JkV7d7x29t" }, "outputs": [], "source": [ "attribute = ['name', 'age', 'gender', 'height', 'weight', 'exercise']\n", "value = ['Sally', 21, 'Female', 160, 50, 0]\n", "\n", "infoDict = dict(zip(attribute, value))\n", "\n", "print(infoDict)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "t1SK2HOjx29x" }, "outputs": [], "source": [ "# 使用 [] 呼叫字典中的 key 取得其對應的 value,和 list 中的 index 類似,只是將 index 換成 key (可為任意型別)。\n", "# 注意每個 key 及 value 都沒有限制型別,因此字典在對應關係上相較只能有整數 index 的 list 自由。\n", "D = {'a': 1, 'b': 2, 'c': 3}\n", "print(D)\n", "\n", "# 在字典中新增一組資料 (key, value),用宣告方式。\n", "D['d'] = 4\n", "print(D)\n", "\n", "# 使用 update(),在字典中添加另一字典的資料\n", "D.update({'e': 5, 'f': 6, 'g': 7})\n", "print(D)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "jAt2CxuBx2-B" }, "outputs": [], "source": [ "D = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6, 'g': 7}\n", "print(D)\n", "\n", "# 使用 del(key) 刪除字典內指定的 (key, value)資料\n", "del (D['a'])\n", "print(D)\n", "\n", "# 使用D.pop(key) 刪除字典內指定的 (key, value)資料, 同時取一次value\n", "print(D.pop('b'))\n", "print(D)\n", "\n", "# 使用 clear() 清空字典內的所有資料\n", "D.clear()\n", "print(D)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "ADT-TYCQx2-c" }, "outputs": [], "source": [ "D = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6, 'g': 7}\n", "\n", "# 使用 keys() 取得所有的 key,並轉成 list\n", "L_keys = list(D.keys())\n", "print(L_keys)\n", "\n", "# 使用 values() 取得所有的 values,並轉成 list\n", "L_values = list(D.values())\n", "print(L_values)\n", "\n", "# 使用 items() 取得所有的 (key, value) tuple, 並轉成 list\n", "L_items = list(D.items())\n", "print(L_items)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "H-juRcPIx2_V" }, "outputs": [], "source": [ "# 使用 in 來尋找 key 或 value 是否在這個字典中\n", "D = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6, 'g': 7}\n", "\n", "# 'a' 目前有在字典的 key 裡,故會印出 True\n", "print('a' in D)\n", "# 'h' 目前不在字典的 key 裡,故會印出 False\n", "print('h' in D)\n", "\n", "# 1 目前存在字典的 values 裡\n", "print(1 in D.values())\n", "# 8 目前不存在字典的 values 裡\n", "print(8 in D.values())" ] }, { "cell_type": "markdown", "metadata": { "id": "9jqm1qQ_x2_e" }, "source": [ "# 複製的注意事項!" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "UffCEdSLx2_e" }, "outputs": [], "source": [ "# 請注意, 如果想複製一份container到另一個名稱上, 必須用.copy(), 否則兩個名稱會對應到同一個container資料\n", "\n", "a = [1]\n", "\n", "b = a\n", "c = a.copy()\n", "\n", "a.clear()\n", "print(b)\n", "print(c)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "FT9u960jbD4w" }, "outputs": [], "source": [ "# 請注意,如果要複製一份 list 到另一個名稱上,必須用 copy(),否則兩個名稱會對應到同一個 list 資料。\n", "\n", "originalList = [1, 2, 3, 4, 5]\n", "\n", "# 如果直接使用等號,則兩個名稱會參考同一份 list,也就是如果對 originalList 修改了資料,\n", "# assignedList 的資料也會被一起更改。\n", "assignedList = originalList\n", "\n", "# 若只用 copy(),則為複製一份一樣的 list。\n", "copyList = originalList.copy()\n", "\n", "# 對 originalList 修改資料\n", "originalList[0] = \"Hello!\"\n", "\n", "# assignedList 也一起被修改\n", "print(assignedList[0])\n", "\n", "# copyList 因為是複製過來的,所以改動原串列對它是不會造成影響的。\n", "print(copyList[0])" ] }, { "cell_type": "markdown", "metadata": { "id": "7Z34SuTqx2_6" }, "source": [ "\n", "\n", "-----\n", "\n" ] }, { "cell_type": "markdown", "metadata": { "id": "wK75itHGbD4x" }, "source": [ "# Quiz" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "MQTHvCvHx2__" }, "outputs": [], "source": [ "# quiz 1\n", "\n", "# 宣告一個 list\n", "# 新增 1 筆任意數字\n", "# 新增 5 筆任意數字\n", "# 逆排序\n", "# 刪除 index 為 3的數字\n", "# 在前面新增 5 個任意數字\n", "# 排序\n", "# 轉換成 tuple" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "0jomvZYxx3Ad" }, "outputs": [], "source": [ "# quiz 3\n", "\n", "# 宣告兩個集合 (set) ,一個集合 (s1) 內有 -3至 5 的所有整數,另一個 (s2) 有 1 至 8 的所有整數\n", "# 印出兩集合的 交集\n", "# 印出兩集合的 聯集\n", "# 印出兩集合互相的 差集" ] } ], "metadata": { "colab": { "name": "Containers.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.7.6" }, "vscode": { "interpreter": { "hash": "f2c5ff1dcfb7037f8bc8783b5d7cd749bee6b69d77e75d46cb9007d97777ae49" } } }, "nbformat": 4, "nbformat_minor": 0 }