欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一篇文章教你掌握python數(shù)據(jù)類型的底層實(shí)現(xiàn)

 更新時(shí)間:2021年09月24日 15:13:17   作者:zlinzju  
這篇文章主要介紹了Python 數(shù)據(jù)類型的底層實(shí)現(xiàn)原理分析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧

在這里插入圖片描述

1. 列表

1.1 復(fù)制

淺拷貝

list_1 = [1, [22, 33, 44], (5, 6, 7), {"name":"Alina"}]
list_3 = list_1        ## 錯(cuò)誤??!只是換了別名
list_2 = list_1.copy() ## 淺拷貝
##或者 也可這樣實(shí)現(xiàn) 
## list_1[:]
## list(list_1)

對(duì)拷貝前后兩個(gè)列表分別進(jìn)行操作

list_2[1].append(55)
print("list_1: ", list_1)
print("list_2: ", list_2)

發(fā)現(xiàn)雖然淺拷貝了,但修改 list_2 的某些元素時(shí),相應(yīng)的 list_1 也有同樣的變化

在這里插入圖片描述

1.2 列表的底層實(shí)現(xiàn) - 淺拷貝

通過 引用數(shù)組 實(shí)現(xiàn)列表元素的存儲(chǔ)

列表中存儲(chǔ)的并不是我們看到的元素的值,而是這些元素的地址

列表所謂的連續(xù),是在內(nèi)存中連續(xù)存儲(chǔ)元素的地址,而元素的值是在內(nèi)存中分散存儲(chǔ)的

當(dāng)訪問到列表的某個(gè)元素時(shí),是按照列表中存儲(chǔ)的元素地址去找到元素的值

直接賦值,是完完全全的沒改變?cè)斜淼娜魏蝺?nèi)容,就是原來的列表多了一個(gè)別名。

淺拷貝,確實(shí)是把列表拷貝了一份,也就是把列表中存儲(chǔ)的地址全部拷貝了一份給新列表,新列表?yè)碛幸环莳?dú)立的地址信息。但這些地址指向的元素和原列表是同一份元素??偨Y(jié),淺拷貝只是把地址重新拷貝了一份,他們指向的內(nèi)容還是同一份內(nèi)容。

在這里插入圖片描述

1.3 淺拷貝 - 示例

在這里插入圖片描述

在這里插入圖片描述

1. 新增元素

在這里插入圖片描述

新增元素時(shí),list_1 列表中新存儲(chǔ)了一個(gè)指向元素100的地址,list_2 列表中新增了一個(gè)指向元素 ‘n' 的地址,因此互不影響。

在這里插入圖片描述

2. 修改元素

當(dāng)我們對(duì) list_1[0]重新賦值的時(shí)候,實(shí)際是把這里原來存儲(chǔ)的指向元素1的地址,替換成了另一個(gè)地址——指向元素10的地址,下次我們?nèi)ist_1[0] 找元素的時(shí)候,會(huì)直接找到元素10,而不會(huì)再和原來的元素1有任何聯(lián)系。同樣的,list_2[0] 存放的地址換成了元素20的地址。

在這里插入圖片描述

在這里插入圖片描述

3. 列表型元素

在這里插入圖片描述

list_1[1] 和 list_2[1] 存放了同一個(gè)地址列表,這個(gè)地址列表指向的也是同一批列表元素,所以修改 list_1[1]和list_2[1]的時(shí)候,都是對(duì)這批列表元素進(jìn)行修改,是同時(shí)更新的。

在這里插入圖片描述

4. 元組型元素

元組是不可變的?。?! 一旦改變了,就不再是這個(gè)元組了,而是一個(gè)新的元組。

所以要對(duì)元組執(zhí)行操作,都是先產(chǎn)生一個(gè)新元組,再在新元組上執(zhí)行相應(yīng)操作。在這里就是先產(chǎn)生了一個(gè)新的地址元組(元組內(nèi)存儲(chǔ)了元素地址),再對(duì)新元組進(jìn)行修改。

在這里插入圖片描述

在這里插入圖片描述

5. 字典型元素

對(duì) list_1里的字典元素,增加一個(gè)鍵值對(duì),發(fā)現(xiàn) list_2 里的字典元素也增加了鍵值對(duì)。

和列表型元素類似,在對(duì)列表型元素操作時(shí),地址列表本身是不變的,我們對(duì)于地址列表的內(nèi)容進(jìn)行操作。

在對(duì)字典型元素操作時(shí),字典散列表本身也是不變的,我們對(duì)于字典散列表的內(nèi)容進(jìn)行操作,按照新增的鍵找到對(duì)應(yīng)位置,把新增的值存進(jìn)去,這個(gè)新增值的存放位置,是由字典的鍵決定的。

在這里插入圖片描述

6. 小結(jié)

列表,字典類型的元素,都是可變的,可以在地址不變的情況下改變內(nèi)容。

而元組,數(shù)字,字符串類型的元素,一旦內(nèi)容發(fā)生變化,那么地址也必須變化。

淺拷貝之后,針對(duì)不可變?cè)兀ㄔM,數(shù)字,字符串)的操作都生效了

針對(duì)可變?cè)兀斜?,字典)的操作,則發(fā)生了一些混淆。

當(dāng)列表中出現(xiàn)了可變類型的元素,我們想對(duì)列表進(jìn)行一個(gè)安全的復(fù)制,使得能夠獨(dú)立操作而不影響原列表,那么就不能淺拷貝,而是需要深拷貝。

1.4 列表的底層實(shí)現(xiàn) - 深拷貝

copy.deepcopy()

深拷貝將所有層級(jí)的相關(guān)元素全部完全的復(fù)制,避免了上述的混淆問題。

在這里插入圖片描述

在這里插入圖片描述

2. 字典

2.1 快速查找

慢 - 列表的查找

import time

ls_1 = list(range(1000000))
ls_2 = list(range(500)) + [-10]*500

start = time.time()
count = 0
for n in ls_2:
	if n in ls_1:
		count += 1
end = time.time()
print("查找{}個(gè)元素,在ls_1中有{}個(gè),共用時(shí){}秒".format(len(ls_2), count, round(end-start)))) 
# 查找1000個(gè)元素,在ls_1中有500個(gè),共用時(shí)6.19秒

快 - 字典的查找

import time

d = {i:i for i in range(1000000)}
ls_2 = list(range(500)) + [-10]*500

start = time.time()
count = 0
for n in ls_2:
	try:
		d[n]
    except:
    	pass
    else:
    	count += 1
end = time.time()
print("查找{}個(gè)元素,在ls_1中有{}個(gè),共用時(shí){}秒".format(len(ls_2), count, round(end-start)))
# 查找1000個(gè)元素,在ls_1中有500個(gè),共用時(shí)0秒

2.2 字典的底層實(shí)現(xiàn)

通過稀疏數(shù)組 實(shí)現(xiàn)值的存儲(chǔ)與訪問

1. 字典的創(chuàng)建過程

1.創(chuàng)建一個(gè)散列表(稀疏數(shù)組,N >>n,可以動(dòng)態(tài)擴(kuò)充

2.通過hash()計(jì)算鍵的散列值

3.根據(jù)計(jì)算的散列值確定其在散列表中的位置(個(gè)別時(shí)候有哈希沖突,解決辦法是開放尋址法 或 鏈接法 )

4.在該位置上存入值

d = {}
# d = dict() 
print(hash("python"))
print(hash(1024))
print(hash(1.2))
# -477104656440599764...
# 1024
# 3713081631934410656...
d["age"] = 18  #增加鍵值對(duì)之前,首先計(jì)算鍵的散列值hash("age")
print(hash("age"))
# 

在這里插入圖片描述

2. 字典的訪問過程

1.計(jì)算要訪問的鍵的散列值

2.根據(jù)計(jì)算的散列值,按照一定的規(guī)則,確定其在散列表中的位置

3.讀取該位置上存儲(chǔ)的值(存在則返回該值,不存在則報(bào)錯(cuò) KeyError)

d["age"]  #訪問鍵值對(duì)之前,首先計(jì)算鍵的散列值hash("age")

2.3 小結(jié)

字典數(shù)據(jù)類型,以空間換時(shí)間,內(nèi)存占用大,空間利用率低,但查找速度快(稀疏數(shù)組 N >> n,否則會(huì)產(chǎn)生很多沖突,另外動(dòng)態(tài)擴(kuò)充也是)因?yàn)殒I在字典中顯示的順序,與實(shí)際計(jì)算出來的它在散列表中的存放位置,是兩碼事,因此字典表現(xiàn)為無序的

之前專門寫過 —— Python字典及底層哈希

3. 字符串

通過緊湊數(shù)組 實(shí)現(xiàn)字符串的存儲(chǔ)

字符串?dāng)?shù)據(jù)在內(nèi)存中是連續(xù)存放的,空間利用率高

原因是:每個(gè)字符的大小是固定的,因此一個(gè)字符串的大小也是固定的,可以分配一個(gè)固定大小的空間給字符串。

同為序列類型,為什么列表采用引用數(shù)組,而字符串采用緊湊數(shù)據(jù)

雖然同為序列類型,但列表可以存儲(chǔ)的元素類型是多種多樣的,并且列表是可變的,無法預(yù)估內(nèi)存空間,所以列表不能通過緊湊數(shù)組。

在這里插入圖片描述

4. 是否可變

不可變類型:數(shù)字,字符串,元組

(元組并不總是不可變的,元組內(nèi)存儲(chǔ)的元素也必須同時(shí)是不可變類型,否則該元組屬于可變)

在生命周期內(nèi)保持內(nèi)容不變,一旦內(nèi)容變了,就不再是它了( id / 地址也變了)

不可變對(duì)象的 += 擴(kuò)充操作,實(shí)際上是創(chuàng)建了一個(gè)新的對(duì)象。

x = 1
print("x id:", id(x))
# x id: 1407184...
x += 2
print("x id:", id(x))
# x id: 204099...

可變類型:列表,字典,集合

id (地址)不變的情況下,里面的內(nèi)容可以改變

可變對(duì)象的 += 操作,實(shí)際是在原對(duì)象的基礎(chǔ)上直接修改

ls = [1,2,3]
print("ls id:", id(ls))
# ls id: 2040991750856
ls += [4,5]
print("ls id:", id(ls))
# ls id: 2040991750856

總結(jié)

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!

相關(guān)文章

  • python多進(jìn)程登錄遠(yuǎn)端服務(wù)器

    python多進(jìn)程登錄遠(yuǎn)端服務(wù)器

    這篇文章主要介紹了python多進(jìn)程登錄遠(yuǎn)端服務(wù)器,文章應(yīng)用實(shí)例簡(jiǎn)易的方式詳細(xì)講解python多進(jìn)程登錄遠(yuǎn)端服務(wù)器的相關(guān)資料,需要的朋友可以參考以下文章的具體內(nèi)容
    2021-10-10
  • pygame中blit()參數(shù)的使用及臟矩形動(dòng)畫形成的說明

    pygame中blit()參數(shù)的使用及臟矩形動(dòng)畫形成的說明

    這篇文章主要介紹了pygame中blit()參數(shù)的使用及臟矩形動(dòng)畫形成的說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • python實(shí)現(xiàn)高精度求自然常數(shù)e過程詳解

    python實(shí)現(xiàn)高精度求自然常數(shù)e過程詳解

    這篇文章主要為大家介紹了python實(shí)現(xiàn)高精度求自然常數(shù)e過程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • python web框架 django wsgi原理解析

    python web框架 django wsgi原理解析

    這篇文章主要介紹了python web框架 django wsgi原理解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值
    2019-08-08
  • Python讀取CSV文件的4種方法與注意事項(xiàng)

    Python讀取CSV文件的4種方法與注意事項(xiàng)

    在python里面,讀取或?qū)懭隿sv文件時(shí)是經(jīng)常遇到的一個(gè)需求,這篇文章主要給大家介紹了關(guān)于Python讀取CSV文件的4種方法與注意事項(xiàng),需要的朋友可以參考下
    2023-10-10
  • 深入了解Python枚舉類型的相關(guān)知識(shí)

    深入了解Python枚舉類型的相關(guān)知識(shí)

    這篇文章主要介紹了深入了解Python枚舉類型的相關(guān)知識(shí),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-07-07
  • 在Docker上開始部署Python應(yīng)用的教程

    在Docker上開始部署Python應(yīng)用的教程

    這篇文章主要介紹了在Docker上開始部署Python應(yīng)用的教程,Docker是時(shí)下最火爆的虛擬機(jī),正在被各大云主機(jī)服務(wù)商所采用,需要的朋友可以參考下
    2015-04-04
  • Python使用post及get方式提交數(shù)據(jù)的實(shí)例

    Python使用post及get方式提交數(shù)據(jù)的實(shí)例

    今天小編就為大家分享一篇關(guān)于Python使用post及get方式提交數(shù)據(jù)的實(shí)例,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • 聊聊python中not 與 is None的區(qū)別

    聊聊python中not 與 is None的區(qū)別

    這篇文章主要介紹了在python中not 與 is None的區(qū)別,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-05-05
  • 基于Python制作B站視頻下載小工具

    基于Python制作B站視頻下載小工具

    這篇文章主要為大家介紹一個(gè)小工具,可以用于B站視頻的下載,只需要輸入對(duì)應(yīng)視頻的網(wǎng)頁(yè)地址就可以進(jìn)行下載到本地了。感興趣的可以了解一下
    2022-01-01

最新評(píng)論