# 小數據池 針對的數據類型: int, str, bool 小數據池能夠幫咱們緩存一個對象. 當重複使用的時候能夠快速的響應. 直接把對象返回. 優勢: 快速拿到對象, 節省內存 缺點: 當小數據池中的內容太多的時候. 程序響應速度是很慢的. # is和== is 比較的是內存地址. == 比較的是內容
# 編碼轉換 encode() : 能夠幫咱們把字符串轉換成bytes類型 decode() : 把bytes類型還原回字符串類型 bytes是字節. 是python中最小的數據單元
1. 基礎數據類型補充 大多數的基本數據類型的知識.已經學完了 join() "*".join("馬虎疼") # 馬*虎*疼 把傳遞進去的參數進行迭代. 獲取到的每一個元素和前面的*進行拼接. 獲得的是字符串 split() 切割. 切割的結果是列表 列表和字典: 都不能在循環的時候直接刪除 (##可迭代對象在循環遍歷的時候是都不能增長元素也不能刪除元素的,列表是刪不乾淨,達不到你要的效果,字典是直接報錯. 總之,在自身遍歷的同時不能改變自身的長度,可是是能夠在遍歷的同時對元素進行修改和查詢的,這個並不會對對象自己的長度形成改變. 列表的改變必定要用到索引去改變元素,字典必定要使用鍵,若是是在遍歷的過程當中直接對列表的元素自己進行修改並賦值,只是改變了中間變量, 並無塞進原來的列表中.字典同理.字典的key就至關於列表的索引) 把要刪除的內容記錄在新列表中而後循環這個新列表. 刪除舊列表(或舊字典) fromkeys() ##是字典的一個方法 坑1: 返回新字典. 不會更改老字典 坑2: 當value是可變的數據類型. 各個key共享同一個可變的數據類型. 其中一個被改變了. 其餘都跟着變 # 程序員找工做和菜市場大媽買白菜是同樣的 2. 深淺拷貝(重點, 難點) 1. = 沒有建立新對象, 只是把內存地址進行了複製 2. 淺拷貝 lst.copy() 只拷貝第一層.(##第一層的含義是遇見內部的元素是可變的數據類型(好比list, set, dict)時仍是隻把內存地址進行拷貝) 3. 深拷貝 import copy copy.deepcopy() 會把對象內部的全部內容進行拷貝
lst = ["alex", "dsb", "wusir", "xsb"] # 使用前面的字符串. 對後面的列表進行拼接,拼接的結果是一個字符串 s = "_".join(lst) print(s) # split() 根據你給的參數進行切割, 切割的結果是列表.##不傳入參數的話,默認是以空白(包括全部的空格,\t,\n)進行分割,長度不相同的空白也當成是相同的分隔符 s = "alex_dsb_wusir_xsb" lst = s.split("_") # 列表 print(lst) # 須要把字符串轉化成列表: str.split()==>lst # 把列表轉化成字符串: "*".join(lst) ==> str # print("*".join("周潤發")) # 用迭代的方式進行的拼接 # 2. 關於刪除 lst = ["籃球", "排球" ,"足球", "電子競技", "檯球"] lst.clear() for el in lst: lst.remove(el) print(lst) # 刪不乾淨.緣由是: 刪除一個. 元素的索引要從新排列, for循環向後走一個. 差一個 for i in range(len(lst)): # 0 1 2 3 4 lst.pop(0) print(lst) lst = ["籃球", "排球" ,"足球", "電子競技", "檯球"] # 最合理的刪除方式: # 1. 把要刪除的內容寫在新列表中. # 2. 循環這個新列表. 刪除老列表 # 需求: 刪除列表中代球字的運動項目 new_lst = [] for el in lst: if "球" in el: new_lst.append(el) # 記錄要刪除的內容 # 要刪除的列表 print(new_lst) # 循環新列表. 刪除老列表 for el in new_lst: # ['籃球', '排球', '足球', '檯球'] lst.remove(el) print(lst) # 字典 # 字典在被循環的時候是不能刪除的. dic = {"張無忌":"乾坤大挪移", "周芷若":"哭", "趙敏":"賣萌"} for k in dic: # dic.pop(k) # dictionary changed size during iteration dic["滅絕師太"] = "倚天屠龍劍" # dictionary changed size during iteration # 把要刪除的key保存在一個新列表中 # 循環這個列表.刪除字典中的key:value lst = [] for k in dic: lst.append(k) # 循環列表 # 刪除字典中的內容 for el in lst: dic.pop(el) print(dic) s = {"楊逍", "範瑤", "韋一笑", "謝遜"} # set集合 for el in s: s.remove(el) # Set changed size during iteration # 集合和字典是一家人(##字典和集合本身自己都是可變的數據類型,而對於內部的元素都有要求) # 字典: key必須是不可變的. 可哈希的, (內部的key是)不重複的 # 集合: 元素必須是不可變的. 可哈希的, (內部的元素是)不重複的 ''' 字典:初始化時候就重複寫key的話,後面的一個會把前面一個的value覆蓋;後面添加已經存在的key的話,是對以前value的修改 集合:初始化時候就重複寫元素的話,只會保留一個;後面添加已經存在的元素的話,添加不進去)(因此有一種說法是:集合就是隻存儲了key的字典 ''' dic = {"韋一笑":"青翼蝠王", "韋一笑":"張無忌"} dic['韋一笑'] = "應天正" # 修改 # 字典的key是惟一的不重複的,對於已經存在的key所作的'添加'是修改 print(dic) # 坑: 大坑, 神坑 # fromkeys() 幫咱們建立字典用的 # 把第一個參數進行迭代. 拿到每一項做爲key和後面的value組合成字典 d = dict.fromkeys("張無忌", "趙敏") # 建立字典 print(d) # 坑1: 返回新字典. 和原來的字典沒有關係 dic = {} d = dic.fromkeys("風扇哥", "很困") print(dic) # {} print(d) # {'風': '很困', '扇': '很困', '哥': '很困'} # # 坑2: 若是value是可變的數據類型, # # 那麼其中一個key對應的value執行的更改操做. 其餘的也跟着變 d = dict.fromkeys("胡辣湯", []) print(d) # {'胡': [], '辣': [], '湯': []} print(id(d['胡'])) print(id(d['辣'])) print(id(d['湯'])) d['胡'].append("河南特點") print(d) # {'胡': ['河南特點'], '辣': ['河南特點'], '湯': ['河南特點']} v = dict.fromkeys(['s1', 's2'], []) v['s1'].append(123) print(v) # {'s1': [123], 's2': [123]} v['s1'] = 567 print(v) # {'s1': 567, 's2': [123]}
#"拼接符".join(可迭代對象) 用迭代的方式進行的拼接,結果是字符串 li = ["李嘉誠」, 」麻花藤」,」黃海峯」,」劉嘉玲"] s = "_".join(li) # 列表轉字符串 print(s) li =「黃花大閨女」 s = "_".join(li) # 字符串的迭代拼接 print(s) # str.split("切割符") 根據你給的分割符進行切割(分割符至關於刀口,不會保留), 切割的結果是列表 s = "alex_dsb_wusir_xsb" lst = s.split("_") # 字符串轉列表 print(lst)
循環刪除列表中的每個元素html
# 使用remove
li = [11, 22, 33,44] for e in li: li . remove(e) print(li) 結果: [22,44]
分析緣由:
for的運行過程會有一個指針來記錄當前循環的元素是哪個.一開始這個指針指向第0個,而後獲取到第0個元素,緊接着刪除第0個.這個時候原來是第一個的元素會自動的變成第0個.而後指針向後移動一次,指向1元素.這時原來的1已經變成了0,也就不會被刪除了.
用del刪除試試看:python
li = [11, 22,33,44] for i in range(0, len(li)): #range只在程序第一次走到 for循環的時候判斷索引範圍(此時len(li)=4),接下去就固定了,不然每次都改變的話,每次都只能是0 del li[i] print(li)
通過分析發現. 循環刪除都不⾏行行. 不管是用del仍是用remove. 都不能實現. 那麼pop呢?程序員
for el in li: li.pop() # pop也不⾏ print(li) 結果: [11, 22] # 循環到元素11,刪除44;循環到元素22,刪除33,再往下就沒有元素能夠繼續了
只有這樣纔是能夠的:面試
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)
注意:因爲刪除元素會致使元素的索引改變, 因此容易出現問題. 盡量不要在循環中直接去刪除元素. 能夠把要刪除的元素添加到另外一個集合中而後再批量刪除. app
dict中的fromkey(),能夠幫咱們經過list來建立一個dictide
dic = dict.fromkeys(["jay", "JJ"], ["周杰倫", "麻花藤"])
print(dic)
結果: {'jay': ['周杰倫', '麻花藤'], 'JJ': ['周杰倫', '麻花藤']}
前⾯列表中的每一項都會做爲key, 後面列表中的內容做爲value. 生成dict編碼
好了. 注意:spa
dic = dict.fromkeys(["jay", "JJ"], ["周杰倫", "麻花藤"])
print(dic)
dic.get("jay").append("胡⼤大")
print(dic)
結果: {'jay': ['周杰倫', '麻花藤', '胡⼤大'], 'JJ': ['周杰倫', '麻花藤', '胡⼤大']}
代碼中只是更改了jay那個列表. 可是因爲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)
""" 首先注意:拷貝會建立新對象,引用不會建立新對象(一個對象一個不一樣的內存地址) =:其實就是對象的引用(別名,二者都指向同一個對象),因此會隨着原對象的操做而徹底同步的變化 深拷貝:徹底拷貝了父對象及其子對象,二者是徹底獨立的,因此徹底不會隨着原對象的操做而發生任何的變化. 淺拷貝:拷貝父對象,不會拷貝父對象內部的子對象,因此a和b是一個獨立的對象,可是他們的子對象仍是指向統一的對象(父對象是拷貝,子對象是引用==>父對象是徹底獨立的,子對象是指向同一個對象的),因此對父對象的操做不會隨之變化,對子對象的操做(只有可變數據類型才能夠對其元素進行增刪改)會隨之變化. 一個形象的比喻: =:把個人做業借給你拿給老師檢查 淺拷貝:你按照個人做業抄了一份給老師檢查,可是少抄了一頁,只抄了'見第二頁' 深拷貝:你按照個人做業抄了一份給老師檢查,連第二頁也抄了 """ # = # # 從上到下只有一個列表被建立 lst1 = ["胡辣湯", "灌湯包", "油潑面", "麻辣香鍋"] lst2 = lst1 # 並無產生新對象. 只是一個指向(內存地址)的賦值 # lst2 = lst1[:] # 切片,是淺拷貝 print(id(lst1)) print(id(lst2)) lst1.append("葫蘆娃") print(lst1) print(lst2) # 淺拷貝 copy 內部元素都是不可變數據類型 lst1 = ["胡辣湯", "灌湯包", "油潑面", "麻辣香鍋"] lst2 = lst1.copy() # 拷貝, 抄做業, 能夠幫咱們建立新的對象,和原來長的如出一轍, 淺拷貝 print(id(lst1)) print(id(lst2)) lst1.append("葫蘆娃") print(lst1) print(lst2) # 淺拷貝 copy 內部元素存在可變數據類型 lst1 = ["胡辣湯", "灌湯包", "油潑面", "麻辣香鍋", ["長白山", "白洋澱", "黃鶴樓"]] lst2 = lst1.copy() # 淺拷貝. 只拷貝第一層內容 print(id(lst1)) print(id(lst2)) print(lst1) print(lst2) lst1[4].append("葫蘆娃") print(lst1) print(lst2) # 深拷貝 deepcopy 無論內部元素是不是可變數據類型,把元素內部的元素徹底進⾏拷⻉複製. 不會產⽣一個改變另⼀個跟着 改變的問題 # 引入一個模塊 import copy lst1 = ["胡辣湯", "灌湯包", "油潑面", "麻辣香鍋", ["長白山", "白洋澱", "黃鶴樓"]] lst2 = copy.deepcopy(lst1) # 深拷貝: 對象內部的全部內容都要複製一份. 深度克隆(clone). 原型模式 print(id(lst1)) print(id(lst2)) # print(lst1) # print(lst2) # # lst1[4].append("葫蘆娃") # print(lst1) # print(lst2) # 爲何要有深淺拷貝? 類比於作做業和抄做業,抄做業是不須要思考的,計算複製也同樣 # 提升建立對象的速度 # 計算機中最慢的. 就是建立對象. 須要分配內存. # 最快的方式就是二進制流的形式進行復制. 速度最快. # 作做業? 抄做業?
= 沒有建立新對象, 只是把內存地址進行了複製
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()
# 或者
# import copy
# lst2 = copy.copy(lst1) # 使用 copy 模塊的 copy.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
深度拷⻉. 把元素內部的元素徹底進⾏拷貝複製. 不會產⽣生一個改變另外一個跟着改變的問題
注意:
針對可變類型而言,淺拷貝只是拷貝"第一層",深拷貝就是拷貝全部層級中的可變類型.
不可變的數據類型深淺拷貝是同樣的效果,都不會產生一個改變另外一個跟着改變的結果.
lst1 = ["胡辣湯", "灌湯包", "油潑面", ["麻辣香鍋"]] lst2 = lst1 # 並無產生新對象. 只是一個指向(內存地址)的賦值 print(id(lst1)) print(id(lst2)) lst1.append("葫蘆娃") lst1[3].append("葫蘆娃") print(lst1) print(lst2) print("---------------------------------------------------------") lst1 = ["胡辣湯", "灌湯包", "油潑面", ["麻辣香鍋"]] lst2 = lst1[:] # 切片,是淺拷貝,經過切片建立新對象,再賦值給lst2 print(id(lst1)) print(id(lst2)) lst1.append("葫蘆娃") lst1[3].append("葫蘆娃") print(lst1) print(lst2) """ 結果: 4361847880 4361847880 ['胡辣湯', '灌湯包', '油潑面', ['麻辣香鍋', '葫蘆娃'], '葫蘆娃'] ['胡辣湯', '灌湯包', '油潑面', ['麻辣香鍋', '葫蘆娃'], '葫蘆娃'] --------------------------------------------------------- 4361848072 4361806280 ['胡辣湯', '灌湯包', '油潑面', ['麻辣香鍋', '葫蘆娃'], '葫蘆娃'] ['胡辣湯', '灌湯包', '油潑面', ['麻辣香鍋', '葫蘆娃']] """
最後咱們來看一個面試題:
a = [1, 2] a[1] = a print(a[1]) # [1, [...]]