1. 程式人生 > >7.set集合,深淺拷貝及補充

7.set集合,深淺拷貝及補充

In 完成 過程 set集合 更新 兩個 淺拷貝 fromkeys dict

本節主要內容:
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 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集合增刪改查
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集合,深淺拷貝及補充