python之set集合及深淺拷貝


一、知識點補充

  1.1字符串的基本操作

   

1 li =["李李嘉誠", "麻花藤", "⻩黃海海峰", "劉嘉玲"]
2 s = "_".join(li)
3 print(s)
4 
5 li = "黃花大閨女"
6 s = "_".join(li)
7 print(s)


1.2列表:

  循環刪除列表中的每一個元素

1 li = [11, 22, 33, 44]
2 for e in li:
3   li.remove(e)
4 print(li)
5 
6 
7 結果:
8 [22, 44]

  分析原因:

    for 循環運行過程中,會有一個指針來記錄當前循環的元素是哪一個,一開始這個指針指向第0個,然后獲取到第0元素,緊接着刪除第0個,這個時候,原來第一個元素會自動的變成第0個,然后指針向后移動一次,指向第1個元素,這時原來的1已經變成了0,也就不會刪除了

  所以刪除只有

1 for i in range(0, len(li)): # 循環len(li)次, 然后從后往前刪除
2   li.pop()
3 print(li)

  或者用另一個列表來記錄你要刪除的內容,然后循環刪除。

1 li = [11, 22, 33, 44]
2 del_li = []
3 for e in li:
4   del_li.append(e)
5 for e in del_li:
6   li.remove(e)
7 print(li)

  注意: 由於刪除元素會導致元素的索引改變, 所以容易易出現問題. 盡量量不要再循環中直接去刪
除元素. 可以把要刪除的元素添加到另⼀一個集合中然后再批量量刪除.

  1.3dict中的fromkey(),可以幫我們通過list來創建⼀一個dict

1 dic = dict.fromkeys(["jay", "JJ"], ["周傑倫", "麻花藤"])
2 print(dic)
3 結果:
4 {'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)

  1.4類型轉換:
  元組 => 列表 list(tuple)
  列表 => 元組 tuple(list)
  list=>str str.join(list)
  str=>list str.split()
  轉換成False的數據:
  0,'',None,[],(),{},set() ==> False

二、set集合

  set集合時python的一個基本數據類型,一般不是很長用,set中的元素是不重復的,無序的,里面的元素必須是可哈希的,我們可以把它看作是dict類型的數據,但是不保存value,只保存key,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)
結果:
{'周星星', '周傑倫'}

   我們可以使用這個特征去掉重復

# 給list去重復
lst = [45, 5, "哈哈", 45, '哈哈', 50]
lst = list(set(lst)) # 把list轉換成set, 然后再轉換回list
print(lst)

  1.1set集合的增、刪、改、查

  1.1.1

  增加

s = {"劉嘉玲", '關之琳', "王祖賢"}
s.add("鄭裕玲")
print(s)
s.add("鄭裕玲") # 重復的內容不不會被添加到set集合中
print(s)
s = {"劉嘉玲", '關之琳', "王祖賢"}
s.update("麻花藤") # 迭代更更新
print(s)
s.update(["張曼⽟", "李若彤","李若彤"])
print(s)

  1.1.2刪除

s = {"劉嘉玲", '關之琳', "王祖賢","張曼⽟", "李若彤"}
item = s.pop() # 隨機彈出⼀一個.
print(s)
print(item)
s.remove("關之琳") # 直接刪除元素
# s.remove("⻢馬⻁虎疼") # 不不存在這個元素. 刪除會報錯
print(s)
s.clear() # 清空set集合.需要注意的是set集合如果是空的. 打印出來是set() 因為要和
dict區分的.
print(s) # set()

  1.1.3修改

# set集合中的數據沒有索引. 也沒有辦法去定位一個元素. 所以沒有辦法進行直接修改.
# 我們可以采⽤先刪除后添加的方式來完成修改操作
s = {"劉嘉玲", '關之琳', "王祖賢","張曼⽟", "李若彤"}
# 把劉嘉玲改成趙本山
s.remove("劉嘉玲")
s.add("趙本山")
print(s)

  1.1.4查詢

# set是⼀一個可迭代對象. 所以可以進⾏行行for循環
for el in s:
  print(el)

  1.2常用操作

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

  都不一樣,深度拷貝,把元素內部的元素完全進行拷貝復制,不會產生一個改變另一個跟着改變的問題

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM