###### tags: `Python` # Python基礎資料型態 ## 4.基本輸入與輸出 ### 4-2格式化輸出資料使用print() #### 4-2-1函數print()的基本語法 ``` print(value,..., sep="",end="",file=sys.stdout,flush=False) ``` 1. value: * 表示像要輸出的資料,可以一次輸出多筆資料,各資料間以逗號隔開。 2. sep: * 當輸出多筆資料時,可以插入各筆資料的分開字元,預設是一個空白字元。 3. end: * 當資料輸出結束時所插入的字元,預設是插入換行字元,所以下一次print()函數的輸出會在下一行輸出。 4. file: * 資料輸出位置,預設是sys.stdout,也就是螢幕輸出。 5. flush: * 是否清除資料流的緩衝區,預設是不清除。 #### 4-2-2 格式化print()輸出 ``` print("..輸出格式區.." % (變數系列區,...)) ``` * %d :格式化整數輸出 * %f :格式化扶點數輸出 * %x :格式化16進位整數輸出 * %o :格式化8進位輸出 * %s :格式化字串輸出 #### 4-2-3 精準控制格式化的輸出 * %(+|-)nd : * %(+|-)m.nf * %(+|-)nx * %(+|-)no * %(-)ns 上述對浮點數而言,m代表保留多少格數供輸出(包含小數點),n則是代表小數資料保留格數。至於其他的資料格式n則是保留多少格數空間,如果保留格數空間不足將完整書出資料,如果保留格數空間太多則資料靠右對齊。 ## 6.list ### 6-4增加與刪除串列元素 #### 6-4-1 在串列末端增加元素 append() ``` name_list.append("新增元素") ``` #### 6-4-2 插入串列元素 insert() append()方法是固定在串列末端插入元素,insert()方法則是可以在任意位置插入元素,它的使用格式如下: ``` name_list.insert(索引,"元素內容") ``` #### 6-4-3 刪除串列元素pop() 使用del刪除串列元素最大的缺點是,資料刪除了就無法取得相關資訊。使用pop()方法刪除元素最大的優點是,刪除後將彈出所刪除的值,使用pop()時若未指明刪除元素的位置,一律刪除串列末端的元素。 ``` value=name_list.pop() #沒有索引是刪除末端元素 value=name_list.pop(i) #刪除指定索引值的串列元素 ``` #### 6-4-4刪除指定的元素remove() 在刪除串列元素時,有時可能不知道元素在串列內的位置,此時可以使用remove()方法刪除指定的元素,它的使用方式如下: ``` name_list.remove(想刪除的元素內容) ``` 如果串列內有相同的元素,則只刪除第一個出現的元素,如果想要刪除所有相同的元素,必須使用迴圈。 #### 6-1-11 刪除串列元素del * 可以使用下列方式刪除指定索引的串列元素: ``` del name_list[i] #刪除索引i的串列元素 ``` * 下列是刪除串列區間元素: ``` del name_list[start:end] #刪除從索引start到(end-1)索引的串列元素 ``` * 下列是刪除區間,但是用step作為每隔多少區間再刪除: ``` del name_list[start:end:step] #每隔step,刪除從索引start到(end-1)索引的串列元素 ``` ### 6-5串列的排序 #### 6-5-1 顛倒排序reverse() reverse()可以顛倒排序串列元素,它的使用方式如下: ``` name_list.reverse() ``` 在切片的應用中,也可以用[::-1]方式取得串列顛倒排序 ``` [::-1] #顛倒排序,不更改串列內容 name_list.reverse() #顛倒排序串列 ``` 串列經顛倒排放後,就算永久性更改了,如果要復原,可以再執行一次reverse()方法。 #### 6-5-2 sort()排序 * 經排序後原串列的元素順序會被永久更改,它的使用格是如下: ``` name_list.sort() ``` 如果是排序英文字串,建議先將字串英文字元全部改成小寫或全部改成大寫。 * sort()方法是允許由大到小,只要在sort()內增加參數"reverse=True"即可。 ``` name_list.sort(reverse=True) ``` #### 6-5-3 sorted()排序 前一小節的sort()排序將造成串列元素順序永久更改,如過不希望更改串列元素順序,可以使用另一種排序sorted(),我們可以用新串列儲存新的排列串列,同時原串列的順序將不更改: ``` new_list = sorted(name_list) #用新串列儲存排序,原串列不更改 ``` 如果我們想要從大到小,可以在sorted()內增加參數"reverse=True": ``` new_list = sorted(name_list,reverse=True) ``` ### 6-6 進階串列操作 #### 6-6-1 index() 這個方法可以傳回特定元素內容第一次出現的索引值: ``` 索引值=串列名稱.index(搜尋值) ``` 如果搜尋值不在串列會出現錯誤 #### 6-6-2 count() 這個方法可以傳回特定元素內容的次數,它的使用格式如下: ``` 次數=串列名稱.count(搜尋值) ``` 如果搜尋值不在串列會出現錯誤 ## 7.range()函數 #### 7-2-1 只有一個參數的range()函數 ``` name_list=list(range(n)) ``` 上述可以產生name_list[0,1,.....,n-1]串列 #### 7-2-2 有2個參數的range()函數 ``` name_list=list(range(start,end)) ``` 上述可以產生name_list[start,.....,end-1]串列,start和end的值可以是負整數,如果終止值小於起始值則產生空串列 #### 7-2-3 有3個參數的range()函數 ``` name_list=list(range(start,end,step)) ``` 從起始值開始產生串列元素,每次間隔step時產生新串列元素,到end-1為止。此外,step值也可以是負數值,此時起始值必須大於終止值。 ## 8.Tuple ### 元組(tuple)的功能 讀者也許好奇,元組的資料結構與串列相同,但是元組有不可更改元素內容的限制,為何Python要有類似但功能卻受限的資料結構存在?原因是tuple有下列優點: * 可以更安全的保護資料: 程式設計中可能會碰上有些資料是永遠不會被改變的事實,將它儲存在元組(tuple)內,可以安全的被保護。例如:電子郵件的資料結構,影像處理食物件的長、寬或每一像素的色彩資料,很多都是以元組為資料類型。 * 增加程式執行速度: 元組(tuple)結構比串列(list)簡單,占用較少的系統資源,程式執行的速度比較快。 當瞭解了上述元組的優點後,其實未來設計程式時,如果確定資料可以不更改,就盡量使用元組類型吧!! ## 9.字典 ### 9-1 字典的基本操作 #### 9-1-3 增加字典元素 ``` name_dict[鍵]=值 ``` #### 9-1-5 刪除字典特定元素 ``` del name_dict[鍵] ``` #### 9-1-6 刪除字典所有元素 使用clear方法刪除所有元素 ``` name_dict.clear() ``` #### 9-1-7 刪除字典 Python也有提供del指令可以將整個字典刪除,字典一經刪除就不再存在 ``` del name_dict ``` #### 9-1-8 建立一個空字典 ``` name_dict={} ``` #### 9-1-9 字典的複製 在大型程式開發過程,也許為了要保護原先字典內容,所以常會需要將字典複製,此時可以使用此方法: ``` new_dict=name_dict.copy() ``` 上述所複製的字典是獨立存在新位址的字典 #### 9-1-10 取得字典元素數量 ``` length=len(name_dict) ``` #### 9-1-11 驗證元素是否存在 ``` 鍵 in name_dict ``` ### 9-2遍歷字典 #### 9-2-1 遍歷字典的鍵-值 name_dict.items() Python有提供方法items(),可以讓我們取得字典 鍵-值 配對的元素 ``` for 變數_1,變數_2 in name_dict.items(): 變數_1..... #第一個變數是 鍵 變數_2..... #第二個變數是 值 ``` 上述只要尚未完成遍歷字典,for 迴圈將持續進行,如此就可以完成遍歷字典,同時傳回所有 鍵-值。 Python的直譯器並不保證字典的順序,因為字典是一個"無序"的資料結構,Python只會保持 鍵-值 不會關注元素的排列順序。 #### 9-2-2 遍歷字典的鍵 name_dict.keys() ``` for i in name_dict.keys(): ``` 其實上述也可以省略keys()方法,而獲的一樣的結果,如下: ``` for i in name_dict: ``` #### 9-2-3 排序與遍歷字典 Python的字典功能並不會處理排序,如果想要遍歷字典同時排序結果,可以使用方法sorted()。 ``` for i in sorted(name_dict.keys()): ``` #### 9-2-4 遍歷字典的值 name_dict.values() Python有提供方法values(),可以讓我們取得字典值列表 ``` for i in name_dict.values(): ``` 在字典的應用中 鍵 不可有重複,值 是可以重複,如果你希望列出的值不要重複,可以使用集合(set)觀念使用set()函數,例如: ``` for i in set(name_dict.values()): ``` ### 9-3 建立字典串列 ``` armys=[] #建立50個小兵 for soldier_number in range(50): soldier={"tag":"red","score":3,"speed":"slow"} armys.append(soldier) #列印前3個小兵 for soldier in armys[:3]: print(soldier) #列印小兵數列 print("小兵數量=",len(armys)) ``` 讀者可能會想上述小兵各種特徵皆相同,用處可能不大,其實對Python而言雖然50個特徵相同的小兵放在串列內,其實每個小兵皆是獨立,可用索引方式存取。 ### 9-4 字典內含串列元素 ``` sports={"Curry":['籃球',"美式足球"], "Durant":["棒球"], "James":["美式足球","棒球","籃球"] } for name,favorite_sport in sports.items(): print("%s 最喜歡的運動是:" %name) for sport in favorite_sport: print(" ",sport) ``` 在Python的應用中也允許將串列放在字典內,這時串列將是字典某鍵的值。如果想要遍歷這類資料結構,需要使用巢狀迴圈和字典的方法items(),外層迴圈是取得字典的鍵,內層迴圈則是將串列的值拆解。 ### 9-5 字典內含字典 ``` wechat_account={"nick":{"last_name":"古", "first_name":"祐宗", "city":"中壢"}, "kevin":{"last_name":"林", "first_name":"恩恩", "city":"台北"}} for account,account_info in wechat_account.items(): print("使用者帳號:",account) name=account_info["last_name"]+" "+account_info["first_name"] print("姓名 =",name) print("城市 =",account_info["city"]) ``` ### 9-6 while迴圈在字典中的應用 ``` survey_dict={} #建立市場調查空字典 market_survey=True #設定迴圈布林值 #讀取參加市場調查者姓名和夢幻旅遊地點 while market_survey: name=input("\n請輸入姓名 :") travel_location=input("夢幻旅遊地點 :") #將輸入存入survey_dict字典 survey_dict[name]=travel_location #可由此決定是否離開市場調查 repeat=input("是否有人要參加市場調查?(y/n) ") if repeat!="y": market_survey=False #市場調查結束 print("\n\n以下是市場調查結果") for user,location in survey_dict.items(): print(user," 的夢幻旅遊地點: ",location) ``` ### 9-7 字典中常用的函數和方法 #### 9-7-1 len() 可以列出字典元素的個數 ``` len(name_dict) ``` #### 9-7-2 fromkeys() 這是建立字典的一個方式,他的語法格是如下: ``` name_dict=dict.fromkeys(seq[, value]) ``` 上述會使用seq序列建立字典,序列內容是字典的鍵,如果沒有設定value則用None當字典鍵的值。 下例分別使用list和tuple建立字典: ``` #將list轉成字典 seq1=["name","city"] list_dict1=dict.fromkeys(seq1) print("字典1 ",list_dict1) list_dict2=dict.fromkeys(seq1,"Chicago") print("字典2 ",list_dict2) #將tuple轉成字典 seq2=("name","city") tuple_dict1=dict.fromkeys(seq2) print("字典1 ",tuple_dict1) tuple_dict2=dict.fromkeys(seq2,"New York") print("字典2 ",tuple_dict2) ``` #### 9-7-3 get() 搜尋字典的鍵,如果鍵存在則傳回該鍵的值,如果不存在則傳回預設值。 ``` ret_value=name_dict.get(key,預設值) #預設值可以不設 ``` key是要搜尋的鍵,如果找不到key則傳回default的值(如果沒設就傳回none)。 #### 9-7-4 setdefault() 這個方法基本上與get()相同,不同之處在於get()方法不會改變字典內容。使用setdefault()方法時若所搜尋的鍵不在,會將 鍵-值 加入字典,如果有字典預設值則將 鍵:預設值 加入字典,如果沒有設定預設值則將 鍵:None加入字典。 ``` ret_value=name_dict.setdefault(key,預設值) #預設值可以不設 ``` ``` #key在字典內 fruits={"apple":20, "orange":25} ret_value1=fruits.setdefault("orange") print("value= :",ret_value1) print("fruit字典 ",fruits) #key不在字典內的應用 person={"name":"nick"} print("原先字典內容",person) #"age"鍵不存在 age=person.setdefault("age") print("增加age鍵",person) print("age= ",age) #"sex"鍵不存在 sex=person.setdefault("sex","male") print("增加sex鍵",person) print("sex= ",sex) ``` #### 9-7-5 pop 這個方法可以刪除字典元素,他的語法如下: ``` ret_value=name_dict.pop(key,default) ``` 上述key是要搜尋刪除元素的鍵,找到時就將該元素從字典內刪除,同時將刪除鍵的值回傳。當找不到key時則傳回default設定的內容 ,如果沒有設定則傳回KeyError。 ``` #使用pop()刪除元素,同時元素存在的應用 fruits={"apple":20,"orange":50} ret_value=fruits.pop("orange") print("傳回刪除元素的值 ",ret_value) print("刪除後的字典內容: ",fruits) #使用pop()刪除元素,同時元素不存在的應用 fruits={"apple":20,"banana":40,"orange":80} ret_value=fruits.pop("grape","does not exist") print("傳回刪除元素的值 ",ret_value) print("刪除後的字典內容: ",fruits) ``` ## 10.Set 集合的基本觀念是無序且每個元素是唯一的,集合元素的內容是不可變的(immutable),常見的元素有整數(integer)、浮點數(float)、字串(string)、元組(tuple)...等。至於可變(mutable)內容串列(list)、字典(dict)、集合(set)...等不可以是集合元素。但是集合本身是可變的(mutable),我們可以增加或刪除集合的元素。 ### 10-1建立集合 Python 可以使用大括號"{}"或set()函數建立集合 #### 10-1-1 使用{}建立集合 ``` name_set={1,2,3,"abcd",(a,b,c,d} #注意元素不能有list ``` 字典是用大括號{}定義,集合也是用{}定義,可否直接使用空的{}定義空集合?? 答案是:"不行!!!!!" 使用空的{}定義,獲得的是空字典 #### 10-1-2 使用set()函數定義集合 除了上述方式建立集合,也可以使用set()函數建立集合,set()函數參數的內容可以是string、list、tuple...等。這時原先string、tuple、list的元素被轉成集合元素。 ``` #這是建立空字典 empty_dict={} #這是建立空集合 empty_set=set() #建立set name_set=set(string、list、tuple) ``` ### 10-2 集合的操作 | Python符號 | 說明|相關method| | -------- | -------- | -------- | | & | 交集 | intersection()| | \| | 聯集 |union()| | - | 差集 |difference()| | ^ | 對稱差集(XOR) | symmetric_difference()| | == | 等於 | | != | 不等於 | | in | 是成員 | | not in | 不是成員 | ``` #A和B的交集 AB=A.intersection(B) #A和B的聯集 AorB=A.union(B) #A和B的差集 A_B=A.difference(B) #A和B的XOR A_sydi_B=A.symmetric_difference(B) ``` ### 10-3 適用集合的method #### 10-3-1 add() ``` name_set.add(新增元素) ``` #### 10-3-2 copy() 集合複製也會像list拷貝一樣。有深度拷貝與淺度拷貝。 copy()是淺度拷貝,經過拷貝後未來一個集合內容改變時,不會影響到另一個集合的內容。 ``` #深度拷貝 numset={1,2,3} deep_numset=numset deep_numset.add(10) print("深度拷貝-觀察numset :",numset) print("深度拷貝-觀察deep_numset :",deep_numset) #淺拷貝 shallow_numset=numset.copy() shallow_numset.add(100) print("淺度拷貝-觀察numset :",numset) print("淺度拷貝-觀察shallow_numset :",shallow_numset) ``` #### 10-3-3 remove() ``` name_set.remove(欲刪除的元素) ``` 若元素不存在set中會有KeyError,若要避免這類錯誤,可以使用discard()。 #### 10-3-4 discard() dicard()可以刪除集合的元素,如果元素不存在也不會有錯誤產生。 ``` ret_value=name_set.dicard(欲刪除的元素) ``` 上述會將集合內,discard()參數指定的元素刪除。不論刪除結果為何,這個方法會傳回none。 #### 10-3-5 pop() pop()是用隨機的方式刪除集合元素,所刪除的元素將被傳回,如果集合是空集合則程式會產生TypeError錯誤。 ``` ret_element=name_set.pop() ``` #### 10-3-6 clear() 刪除集合內所有的元素,傳回值是none ``` name_set.clear() ``` #### 10-3-7 isdisjoint() 如果2個集合沒有共同的元素會傳回True,否則傳回False。 沒有交集->True,有交集->False ``` ret_boolean=name_set.isdisjoint() ``` #### 10-3-8 issubset() ``` boolean=A.issubset(B) ``` #### 10-3-9 issuperset() ``` boolean=A.issuperset(B) ``` #### 10-3-10 intersection_update() 這個方法會直接改變set的內容 ``` ret_value=A.intersection_update(*B) ``` 上述*B代表是可以有1到多個集合,如果只有一個集合,例如是B,則執行後A將是A與B的交集。如果*B代表(B,C),則執行後A將是A、B、C交集。 上述傳回值是None,此值將設定給ret_value,接下來幾個小節的方法皆會傳回None,將不再敘述。 #### 10-3-11 update() 可以將一個集合的元素加到呼叫此方法的集合內,語法如下: ``` name_setA.update(name_setB) ``` 上述是將集合B的元素加到集合A中。 #### 10-3-12 difference_update() ``` name_setA.difference_update(name_setB) ``` #### 10-3-13 symmetric_difference_update() ``` name_setA.symmetric_difference_update(name_setB) ``` ### 10-4 適用集合的基本函數操作 | 函數名稱| 說明 | | -------- | -------- | | enumerate() | 傳回連續整數配對的enumerate物件 | len() | 元素數量 | | max() | 最大值 | |min() | 最小值 | |sorted() | 傳回已經排序的串列,集合本身則不改變 | |sum() | 總和 | ### 10-5 frozenset set是可變集合,frozenset是不可變集合也可以直譯為凍結集合,這是一個新的類別(class),只要設定元素後,這個凍結集合就不能再更改了。如果將tuple想成不可變的list,frozenset就是不可變的set。 frozenset的不可變特性優點是可以用它做字典的key,也可以做為其他集合的元素。frozenset的建立方式是使用frozenset()函數,凍結集合建立完成後,不可使用add()或remove()更動凍結集合的內容。但是可以執行intersection()、union()、difference()、symmetric_difference、copy()、issubset()、issuperset()、isdisjoint()等方法。 ``` name_frozenset=frozenset(list、tuple、set) ```