1. 程式人生 > >python深淺拷貝,集合以及數據類型的補充

python深淺拷貝,集合以及數據類型的補充

指向 最好 大小 epc app 列表 keys hang 變化

1.基礎數據類型的補充

1.元組

如果元組中只有一個數據,且沒有逗號,則該‘元組’與裏面的數據的類型相同。如:

1 tu = (1)
2 tu1 = (1,)
3 tu2 = (alex)
4 tu3 = ([1,2,3],)
5 print(tu,type(tu))    # 1 <class ‘int‘>
6 print(tu1,type(tu1))  # (1,) <class ‘tuple‘>
7 print(tu2,type(tu2))  # alex <class ‘str‘>
8 print(tu3,type(tu3))  # ([1, 2, 3],) <class ‘tuple‘>

2. 列表

列表與列表是可以相加的,如:

1 l1 = [1,2,3]
2 l2 = [alex,wusir]
3 l3 = l1 + l2  # [1, 2, 3, ‘alex‘, ‘wusir‘]
4 print(l3)

如何將列表中的索引為奇數的元素刪除,如例題: l1 = [11, 22, 33, 44, 55, 66, 77, 88]

1 l1 = [11, 22, 33, 44, 55, 66, 77, 88]
2 for i in range(len(l1)):
3     if i % 2 == 1:
4         l1.pop(i)
5 print(l1)      #
IndexError: pop index out of range

上面的代碼看似正確,但執行後卻報錯,報錯解釋為:

IndexError: pop index out of range

經過分析後可知,每當pop()一次後,將奇數位刪除,此時,刪除位之後的元素會向前移動一位,導致l1的索引會不斷的發生變化。因此,本文提出了三種解決方法:

第一種:切片 + 步長刪除

1 l1 = [11, 22, 33, 44, 55, 66, 77, 88]
2 del l1[1::2]
3 print(l1)

第二種方法:

1 l1 = [11, 22, 33, 44, 55, 66, 77, 88]
2 l2 = [] # 重新創建一個空列表 3 for i in range(len(l1)): 4 if i % 2 == 0: 5 l2.append(l1[i]) 6 l1 = l2 # 用l2去覆蓋l1 7 print(l1)

第三種方法:按照倒序刪除:

1 for index in range(len(l1)-1, -1, -1):
2     if index % 2 == 1:
3         l1.pop(index)
4 print(l1)

綜上分析:在循環一個列表時,最好不要對此列表直接進行改變大小(增刪)操作。

3. 字典

字典的創建方式(三種:面試常考)

1 #1,
2 dic = {name:alex}
3 #2
4 dic = dict({name:alex})
5 print(dic)
6 #3, fromkeys()
7 dic1 = dict.fromkeys([1,2,3],alex)
8 print(dic1)

但是,在第三種創建方式下,有別於第一種和第二種方式:

1 dic1 = dict.fromkeys([1,2,3],[])
2 print(dic1)     # {1: [], 2: [], 3: []}
3 dic1[1].append(alex)
4 print(dic1)      # {1: [‘alex‘], 2: [‘alex‘], 3: [‘alex‘]}
5 print(id(dic1[1]))   # 1478241524744
6 print(id(dic1[2]))   # 1478241524744
7 print(id(dic1[3]))   # 1478241524744

如何將字典的鍵中含有k元素的所有鍵值對刪除。如例題:dic = {‘key1‘: ‘value1‘,‘key2‘: ‘value2‘, ‘k3‘:‘v3‘, ‘name‘: ‘alex‘}

如果按照下面這種方式去處理會得到如下結果:

1 dic = {key1: value1,key2: value2, k3:v3, name: alex}
2 for key in dic:
3     if k in key:
4         dic.pop(key)
5 print(dic)

運行代碼時,會發生報錯,報錯解釋為:dictionary changed size during iteration

其分析結果與列表分析一樣,這是由於在循環一個字典時,不能改變字典的大小。因此解決方案是可以創建一個新的列表,先用來存儲需要刪除的鍵,然後通過遍歷這個列表,去刪除原字典中對應有的鍵。解題如下:

1 dic = {key1: value1,key2: value2, k3:v3, name: alex}
2 l1 = []
3 for key in dic:
4     if k in key:
5         l1.append(key)
6 # print(l1)
7 for key in l1:
8     dic.pop(key)
9 print(dic)

2.集合

集合是無序的,不重復的數據集合,它裏面的元素是可哈希的(不可變類型),但是集合本身是不可哈希(所以集合做不了字典的鍵)的。

集合元素的數據類型通常為:元組,整數,字符串,bool值等。

集合的創建方式,有兩種:

1 set1 = {alex, [1,2], 1,2,3}
2 set1 = {alex, wusir}
3 set2 = set({alex, wusir})
4 print(set2)

如何用list去重操作(面試題常考):

1 l1 = [1,1,2,3,4,4,3,2,1,5,5]
2 set1 = set(l1)
3 l2 = list(set1)
4 print(l2)

不可變數據類型:

1 set1 = {1,2,3}
2 set3 = frozenset(set1)
3 print(set3)  # 不可變的數據類型。  ***

3 深淺拷貝

1 淺拷貝

什麽是淺拷貝???我們先來看一個例題:

1 # 列表只有一層,無嵌套情況
2 l1 = [1,2,3]
3 l2 = l1
4 l1.append(666)
5 print(l2)
6 print(id(l1))   # 2309663104392
7 print(id(l2))   # 2309663104392
1 # 有內層嵌套的列表
2 l1 = [1,2,3,[22,]]
3 l2 = l1.copy()
4 l1[-1].append(taibai)
5 print(l1,l2)   # [1, 2, 3, [22, ‘taibai‘]] [1, 2, 3, [22, ‘taibai‘]]
6 print(id(l1))   # 1787284757960
7 print(id(l2))   # 1787285576712
8 print(id(l1[-1]))   # 1787284757896
9 print(id(l2[-1]))   # 1787284757896

從上面的分析可以看出,對於淺copy來說,第一層創建的是新的內存地址,而從第二層開始,指向的都是同一個內存地址,所以,對於第二層以及更深的層數來說,保持一致性。

2.深拷貝

同樣,先舉一個例子來看看什麽是深拷貝:

1 import copy
2 l1 = [1,2,3,[22,]]
3 l2 = copy.deepcopy(l1)
4 l1[-1].append(太白)
5 print(l1,l2)   # [1, 2, 3, [22, ‘太白‘]] [1, 2, 3, [22]]
6 print(id(l1))   # 1763810759304
7 print(id(l2))   # 1763810760584
8 print(id(l1[-1]))   # 1763810759112
9 print(id(l2[-1]))   # 1763810760520

從上面的分析我們可以知道:對於深copy來說,兩個是完全獨立的,改變任意一個的任何元素(無論多少層),另一個絕對不改變。

深淺拷貝應用的場景:面試常考,讓你解釋深淺拷貝。

# 完全獨立的copy一份數據,與原數據沒有關系,深copy

# 如果一份數據(列表)第二層時,你想與原數據進行公用,淺copy。

另外:切片也屬於淺拷貝,例如:

1 l1 = [1,2,3,[22,33]]
2 l2 = l1[:]
3 l1[-1].append(666)
4 print(l1,l2)   # [1, 2, 3, [22, 33, 666]] [1, 2, 3, [22, 33, 666]]
5 print(id(l1))   # 1234866347400
6 print(id(l2))   # 1234867166216
7 print(id(l1[-1]))   # 1234866347464
8 print(id(l2[-1]))   # 1234866347464

python深淺拷貝,集合以及數據類型的補充