###### 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)
```