1. 程式人生 > >set集合,深淺拷貝以及部分知識點補充

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來說,兩個是完全獨立的,改變任意一個的任何元素(無論多少層).另一個絕對不改變