7.set集合,深淺拷貝及補充
本節主要內容:
1. 基礎數據類型補充
2. set集合
3. 深淺拷?貝
主要內容:
?一. 基礎數據類型補充
?首先關於int和str在之前的學習中已經講了了80%以上了了. 所以剩下的?自?己看?一看就可以了了.
我們補充給?一個字符串串基本操作
li = ["李李嘉誠", "麻花藤", "?黃海?峰", "劉嘉玲"] s = "_".join(li) print(s) li = "?黃花?大閨?女女" s = "_".join(li) print(s)
列列表:
循環刪除列列表中的每?一個元素
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 indel_li: li.remove(e) print(li)
註意: 由於刪除元素會導致元素的索引改變, 所以容易易出現問題. 盡量量不要再循環中直接去刪
除元素. 可以把要刪除的元素添加到另?一個集合中然後再批量量刪除.
dict中的fromkey(),可以幫我們通過list來創建?一個dict
dic = dict.fromkeys(["jay", "JJ"], ["周傑倫", "麻花藤"]) print(dic) 結果: {‘jay‘: [‘周傑倫‘, ‘麻花藤‘], ‘JJ‘: [‘周傑倫‘, ‘麻花藤‘]}
前?面列列表中的每?一項都會作為key, 後?面列列表中的內容作為value. ?生成dict
好了了. 註意:
dic = dict.fromkeys(["jay", "JJ"], ["周傑倫", "麻花藤"]) print(dic) dic.get("jay").append("胡?大") print(dic) 結果: {‘jay‘: [‘周傑倫‘, ‘麻花藤‘, ‘胡?大‘], ‘JJ‘: [‘周傑倫‘, ‘麻花藤‘, ‘胡?大‘]}
代碼中只是更更改了了jay那個列列表. 但是由於jay和JJ?用的是同?一個列列表. 所以. 前?面那個改了了. 後
?面那個也會跟著改
dict中的元素在叠代過程中是不允許進?行行刪除的
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
?二. set集合
set集合是python的?一個基本數據類型. ?一般不是很常?用. set中的元素是不重復的.?無序的.?裏裏
?面的元素必須是可hash的(int, str, tuple,bool), 我們可以這樣來記. set就是dict類型的數據但
是不保存value, 只保存key. set也?用{}表?示
註意: set集合中的元素必須是可hash的, 但是set本身是不可hash得. set是可變的.
set1 = {‘1‘,‘alex‘,2,True,[1,2,3]} # 報錯 set2 = {‘1‘,‘alex‘,2,True,{1:2}} # 報錯 set3 = {‘1‘,‘alex‘,2,True,(1,2,[2,3,4])} # 報錯
set中的元素是不重復的, 且?無序的.
s = {"周傑倫", "周傑倫", "周星星"} print(s) 結果: {‘周星星‘, ‘周傑倫‘}
使?用這個特性.我們可以使?用set來去掉重復
# 給list去重復 lst = [45, 5, "哈哈", 45, ‘哈哈‘, 50] lst = list(set(lst)) # 把list轉換成set, 然後再轉換回list print(lst)
set集合增刪改查
1. 增加
s = {"劉嘉玲", ‘關之琳‘, "王祖賢"} s.add("鄭裕玲") print(s) s.add("鄭裕玲") # 重復的內容不不會被添加到set集合中 print(s) s = {"劉嘉玲", ‘關之琳‘, "王祖賢"} s.update("麻花藤") # 叠代更更新 print(s) s.update(["張曼?玉", "李李若彤","李李若彤"]) print(s)
2. 刪除
s = {"劉嘉玲", ‘關之琳‘, "王祖賢","張曼?玉", "李李若彤"} item = s.pop() # 隨機彈出?一個. print(s) print(item) s.remove("關之琳") # 直接刪除元素 # s.remove("?馬?虎疼") # 不不存在這個元素. 刪除會報錯 print(s) s.clear() # 清空set集合.需要註意的是set集合如果是空的. 打印出來是set() 因為要和 dict區分的. print(s) # set()
3. 修改
# set集合中的數據沒有索引. 也沒有辦法去定位?一個元素. 所以沒有辦法進?行行直接修改. # 我們可以采?用先刪除後添加的?方式來完成修改操作 s = {"劉嘉玲", ‘關之琳‘, "王祖賢","張曼?玉", "李李若彤"} # 把劉嘉玲改成趙本?山 s.remove("劉嘉玲") s.add("趙本?山") print(s)
4. 查詢
# set是?一個可叠代對象. 所以可以進?行行for循環 for el in s: print(el)
5. 常?用操作
s1 = {"劉能", "趙四", "?皮?長?山"} s2 = {"劉科?長", "馮鄉?長", "?皮?長?山"} # 交集 # 兩個集合中的共有元素 print(s1 & s2) # {‘?皮?長?山‘} print(s1.intersection(s2)) # {‘?皮?長?山‘} # 並集 print(s1 | s2) # {‘劉科?長‘, ‘馮鄉?長‘, ‘趙四‘, ‘?皮?長?山‘, ‘劉能‘} print(s1.union(s2)) # {‘劉科?長‘, ‘馮鄉?長‘, ‘趙四‘, ‘?皮?長?山‘, ‘劉能‘} # 差集 print(s1 - s2) # {‘趙四‘, ‘劉能‘} 得到第?一個中單獨存在的 print(s1.difference(s2)) # {‘趙四‘, ‘劉能‘} # 反交集 print(s1 ^ s2) # 兩個集合中單獨存在的數據 {‘馮鄉?長‘, ‘劉能‘, ‘劉科?長‘, ‘趙四‘} print(s1.symmetric_difference(s2)) # {‘馮鄉?長‘, ‘劉能‘, ‘劉科?長‘, ‘趙四‘} s1 = {"劉能", "趙四"} s2 = {"劉能", "趙四", "?皮?長?山"} # ?子集 print(s1 < s2) # set1是set2的?子集嗎? True print(s1.issubset(s2)) # 超集 print(s1 > s2) # set1是set2的超集嗎? False print(s1.issuperset(s2))
set集合本身是可以發?生改變的. 是不可hash的. 我們可以使?用frozenset來保存數據.
frozenset是不可變的. 也就是?一個可哈希的數據類型
s = frozenset(["趙本?山", "劉能", "?皮?長?山", "?長跪"]) dic = {s:‘123‘} # 可以正常使?用了了 print(dic)
這個不是很常?用. 了了解?一下就可以了了
三. 深淺拷?貝
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
都不?一樣了了. 深度拷?貝. 把元素內部的元素完全進?行行拷?貝復制. 不會產?生?一個改變另?一個跟著
改變的問題
7.set集合,深淺拷貝及補充