編碼轉換,基礎,copy
閱讀目錄
一,編碼轉換
1. ASCII : 最早的編碼. ⾥⾯有英⽂⼤寫字⺟, ⼩寫字⺟, 數字, ⼀些特殊字元.
沒有中⽂, 8個01程式碼, 8個bit, 1個byte
2. GBK: 中⽂國標碼, ⾥⾯包含了ASCII編碼和中⽂常⽤編碼. 16個bit, 2個byte
3. UNICODE: 萬國碼, ⾥⾯包含了全世界所有國家⽂字的編碼. 32個bit, 4個byte, 包含了 ASCII
4. UTF-8: 可變⻓度的萬國碼. 是unicode的⼀種實現. 最⼩字元佔8位
1.英⽂: 8bit 1byte
2.歐洲⽂字:16bit 2byte
3.中⽂:24bit 3byte
綜上, 除了ASCII碼以外, 其他資訊不能直接轉換.
在python3的記憶體中. 在程式運⾏階段. 使⽤的是unicode編碼.
因為unicode是萬國碼. 什麼內容都可以進⾏顯⽰. 那麼在資料傳輸和儲存的時候由於unicode比較浪費空間和資源.
需要把 unicode轉存成UTF-8或者GBK進⾏儲存. 怎麼轉換呢.
在python中可以把⽂字資訊進⾏編碼. 編碼之後的內容就可以進⾏傳輸了.
編碼之後的資料是bytes型別的資料.其實啊. 還是原來的 資料只是經過編碼之後表現形式發⽣了改變⽽已.
bytes的表現形式:
1. 英⽂ b'alex' 英⽂的表現形式和字串沒什麼兩樣
2. 中⽂ b'\xe4\xb8\xad' 這是⼀個漢字的UTF-8的bytes表現形式
s = "alex" print(s.encode("utf-8")) # 將字串編碼成UTF-8 print(s.encode("GBK")) # 將字串編碼成GBK 結果: b'alex' b'alex' s = "中" print(s.encode("UTF-8")) # 中⽂編碼成UTF-8 print(s.encode("GBK")) # 中⽂編碼成GBK 結果: b'\xe4\xb8\xad' b'\xd6\xd0'
記住: 英⽂編碼之後的結果和源字串⼀致. 中⽂編碼之後的結果根據編碼的不同. 編碼結果也不同.
我們能看到. ⼀箇中⽂的UTF-8編碼是3個位元組. ⼀個GBK的中⽂編碼是2個位元組.
編碼之後的型別就是bytes型別. 在⽹絡傳輸和儲存的時候我們python是儲存和儲存的bytes 型別.
那麼在對⽅接收的時候. 也是接收的bytes型別的資料. 我們可以使⽤decode()來進⾏解 碼操作.
把bytes型別的資料還原回我們熟悉的字串:
s = "我叫李嘉誠" print(s.encode("utf-8")) # b'\xe6\x88\x91\xe5\x8f\xab\xe6\x9d\x8e\xe5\x98\x89\xe8\xaf\x9a' print(b'\xe6\x88\x91\xe5\x8f\xab\xe6\x9d\x8e\xe5\x98\x89\xe8\xaf\x9a'.decod e("utf-8")) # 解碼
編碼和解碼的時候都需要制定編碼格式.
s = "我是⽂字" bs = s.encode("GBK") # 我們這樣可以獲取到GBK的⽂字 # 把GBK轉換成UTF-8 # ⾸先要把GBK轉換成unicode. 也就是需要解碼 s = bs.decode("GBK") # 解碼 # 然後需要進⾏重新編碼成UTF-8 bss = s.encode("UTF-8") # 重新編碼 print(bss)
基礎的補充
我們補充給幾個資料型別的操作
lst = [1,2,3,4,5,6] for i in lst: lst.append(7) # 這樣寫法就會一直持續新增7 print(lst) print(lst)
列表: 迴圈刪除列表中的每⼀個元素
li = [11, 22, 33, 44] for e in li: li.remove(e) print(li) 結果: [22, 44]
分析原因: for的運⾏過程. 會有⼀個指標來記錄當前迴圈的元素是哪⼀個, ⼀開始這個指標指向第0 個.
然後獲取到第0個元素. 緊接著刪除第0個. 這個時候. 原來是第⼀個的元素會⾃動的變成 第0個.
然後指標向後移動⼀次, 指向1元素. 這時原來的1已經變成了0, 也就不會被刪除了.
⽤pop刪除試試看:
li = [11, 22, 33, 44] for i in range(0, len(li)): del li[i] print(li) 結果: 報錯 # i= 0, 1, 2 刪除的時候li[0] 被刪除之後. 後⾯⼀個就變成了第0個. # 以此類推. 當i = 2的時候. list中只有⼀個元素. 但是這個時候刪除的是第2個 肯定報錯啊
經過分析發現. 迴圈刪除都不⾏. 不論是⽤del還是⽤remove. 都不能實現. 那麼pop呢?
for el in li: li.pop() # pop也不⾏ print(li) 結果: [11, 22]
只有這樣才是可以的:
for i in range(0, len(li)): # 迴圈len(li)次, 然後從後往前刪除 li.pop() print(li)
或者.用另一種類表來記錄你要刪除的內容.然後迴圈的刪除
li = [11, 22, 33, 44] del_li = [] for e in li: del_li.append(e) for e in del_li: li.remove(e) print(li)
注意:
由於刪除元素會導致元素的索引改變,所以容易出現問題,儘量不要在迴圈中直接去刪除元素,可以吧要刪除的元素新增到另一個集合中然後在批量刪除
dict中的fromkey(),可以幫助我們通過list來建立一個dict
dic = dict.fromkeys(["jay", "JJ"], ["周杰倫", "麻花藤"]) print(dic) 結果: {'jay': ['周杰倫', '麻花藤'], 'JJ': ['周杰倫', '麻花藤']}
程式碼中的元素在迭代過程中是不允許進行刪除的
dic = {'k1': 'alex', 'k2': 'wusir', 's1': '⾦⽼板'} # 刪除key中帶有'k'的元素 for k in dic: if 'k' in k: del dic[k] # dictionary changed size during iteration, 在迴圈迭 代的時候不允許進⾏刪除操作 print(dic)
那怎麼辦呢? 把要刪除的元素暫時先儲存在⼀個list中, 然後迴圈list, 再刪除
dic = {'k1': 'alex', 'k2': 'wusir', 's1': '⾦⽼板'} dic_del_list = [] # 刪除key中帶有'k'的元素 for k in dic: if 'k' in k: dic_del_list.append(k) for el in dic_del_list: del dic[el] print(dic)
型別轉換:
元組 => 列表 list(tuple)
列表 => 元組 tuple(list)
list=>str str.join(list)
str=>list str.split()
轉換成False的資料:
0,'',None,[],(),{},set() ==> False
深淺拷貝
lst1 = ["⾦⽑獅王", "紫衫⻰王", "⽩眉鷹王", "⻘翼蝠王"] lst2 = lst1 print(lst1) print(lst2) lst1.append("楊逍") print(lst1) print(lst2) 結果: ['⾦⽑獅王', '紫衫⻰王', '⽩眉鷹王', '⻘翼蝠王', '楊逍'] ['⾦⽑獅王', '紫衫⻰王', '⽩眉鷹王', '⻘翼蝠王', '楊逍'] dic1 = {"id": 123, "name": "謝遜"} dic2 = dic1 print(dic1) print(dic2) dic1['name'] = "範瑤" print(dic1) print(dic2) 結果: {'id': 123, 'name': '謝遜'} {'id': 123, 'name': '謝遜'} {'id': 123, 'name': '範瑤'} {'id': 123, 'name': '範瑤'}
對於list, set, dict來說, 直接賦值. 其實是把記憶體地址交給變數. 並不是複製⼀份內容. 所以. lst1的記憶體指向和lst2是⼀樣的. lst1改變了, lst2也發⽣了改變
淺拷貝
lst1 = ["何炅", "杜海濤","周渝⺠"] lst2 = lst1.copy() lst1.append("李嘉誠") print(lst1) print(lst2) print(id(lst1), id(lst2)) 結果: 兩個lst完全不⼀樣. 記憶體地址和內容也不⼀樣. 發現實現了記憶體的拷⻉ lst1 = ["何炅", "杜海濤","周渝⺠", ["麻花藤", "⻢芸", "周筆暢"]] lst2 = lst1.copy() lst1[3].append("⽆敵是多磨寂寞") print(lst1) print(lst2) print(id(lst1[3]), id(lst2[3])) 結果: ['何炅', '杜海濤', '周渝⺠', ['麻花藤', '⻢芸', '周筆暢', '⽆敵是多磨寂寞']] ['何炅', '杜海濤', '周渝⺠', ['麻花藤', '⻢芸', '周筆暢', '⽆敵是多磨寂寞']] 4417248328 4417248328
淺拷⻉. 只會拷⻉第⼀層. 第⼆層的內容不會拷⻉. 所以被稱為淺拷⻉
深拷⻉
import copy lst1 = ["何炅", "杜海濤","周渝⺠", ["麻花藤", "⻢芸", "周筆暢"]] lst2 = copy.deepcopy(lst1) lst1[3].append("⽆敵是多磨寂寞") print(lst1) print(lst2) print(id(lst1[3]), id(lst2[3])) 結果: ['何炅', '杜海濤', '周渝⺠', ['麻花藤', '⻢芸', '周筆暢', '⽆敵是多磨寂寞']] ['何炅', '杜海濤', '周渝⺠', ['麻花藤', '⻢芸', '周筆暢']] 4447221448 4447233800
都不⼀樣了.
深度拷貝. 把元素內部的元素完全進行拷貝複製. 不會產⽣⼀個改變另⼀個跟著 改變的問題 補充⼀個知識點:
最後我們來看⼀個⾯試題:
a = [1, 2] a[1] = a print(a[1])