set集合,深淺拷貝以及部分知識點補充
目錄:
1.基礎資料型別補充
2.set集合
3.深淺拷貝
一,基礎資料型別補充
字串的基本操作
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個 肯定報錯啊
只有這樣才是可以的:
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': ['周杰倫', '麻花藤']}
前面列表中的每一項都會作為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集合增刪改查
增加
s = {"劉嘉玲", '關之琳', "王祖賢"} s.add("鄭裕玲") print(s) s.add("鄭裕玲") # 重複的內容不會被新增到set集合中 print(s) s = {"劉嘉玲", '關之琳', "王祖賢"} s.update("麻花藤") # 迭代更新 print(s) s.update(["張曼⽟", "李若彤","李若彤"]) print(s)
刪除
s = {"劉嘉玲", '關之琳', "王祖賢","張曼⽟", "李若彤"} item = s.pop() # 隨機彈出⼀個. print(s) print(item) s.remove("關之琳") # 直接刪除元素 # s.remove("⻢⻁疼") # 不存在這個元素. 刪除會報錯 print(s) s.clear() # 清空set集合.需要注意的是set集合如果是空的. 打印出來是set() 因為要和 dict區分的. print(s) # set()
修改
# set集合中的資料沒有索引. 也沒有辦法去定位⼀個元素. 所以沒有辦法進⾏直接修改. # 我們可以採⽤先刪除後新增的⽅式來完成修改操作 s = {"劉嘉玲", '關之琳', "王祖賢","張曼⽟", "李若彤"} # 把劉嘉玲改成趙本⼭ s.remove("劉嘉玲") s.add("趙本⼭") print(s)
查詢
# set是⼀個可迭代物件. 所以可以進⾏for迴圈 for el in s: print(el)
查詢的方法只能使用for迴圈進行操作
常用的操作
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)
這個不用是不用一用到,絕對是牛逼的解法
注意:
set本身是不可雜湊的,但是set集合中的元素是可hash的不可變的
深淺拷貝
1.對比賦值運算
l1 = [1,2,3,['barry','alex']] l2 = l1 l1[0] = 111 print(l1) # [111, 2, 3, ['barry', 'alex']] print(l2) # [111, 2, 3, ['barry', 'alex']] l1[3][0] = 'wusir' print(l1) # [111, 2, 3, ['wusir', 'alex']] print(l2) # [111, 2, 3, ['wusir', 'alex']]
對於賦值運算來說.l1與l2指向的是同一個記憶體地址,所以他們是完全一樣的
2.淺拷貝
l1 = [1,2,3,['barry','alex']] l2 = l1.copy() print(l1,id(l1)) # [1, 2, 3, ['barry', 'alex']] 2380296895816 print(l2,id(l2)) # [1, 2, 3, ['barry', 'alex']] 2380296895048 l1[1] = 222 print(l1,id(l1)) # [1, 222, 3, ['barry', 'alex']] 2593038941128 print(l2,id(l2)) # [1, 2, 3, ['barry', 'alex']] 2593038941896 l1[3][0] = 'wusir' print(l1,id(l1[3])) # [1, 2, 3, ['wusir', 'alex']] 1732315659016 print(l2,id(l2[3])) # [1, 2, 3, ['wusir', 'alex']] 1732315659016
對於錢copy來說,第一層建立的是新的記憶體地址,而從第二層開始,指向的都是同一個記憶體地址,所以對於第二層以及更深的層數來說.保持一致性.
3.深拷貝deepcopy
import copy l1 = [1,2,3,['barry','alex']] l2 = copy.deepcopy(l1) print(l1,id(l1)) # [1, 2, 3, ['barry', 'alex']] 2915377167816 print(l2,id(l2)) # [1, 2, 3, ['barry', 'alex']] 2915377167048 l1[1] = 222 print(l1,id(l1)) # [1, 222, 3, ['barry', 'alex']] 2915377167816 print(l2,id(l2)) # [1, 2, 3, ['barry', 'alex']] 2915377167048 l1[3][0] = 'wusir' print(l1,id(l1[3])) # [1, 222, 3, ['wusir', 'alex']] 2915377167240 print(l2,id(l2[3])) # [1, 2, 3, ['barry', 'alex']] 2915377167304
對於深copy來說,兩個是完全獨立的,改變任意一個的任何元素(無論多少層).另一個絕對不改變