在 Python 中,有四類最常見的內(nèi)建容器類型:
列表(list)
、
元組(tuple)
、
字典(dict)
、
集合(set)
。通過單獨(dú)或是組合使用它們,可以高效的完成很多事情。
Python 語言自身的內(nèi)部實(shí)現(xiàn)細(xì)節(jié)也與這些容器類型息息相關(guān)。比如 Python 的類實(shí)例屬性、全局變量
globals()
等就都是通過字典類型來存儲的。
在這篇文章里,我首先會從容器類型的定義出發(fā),嘗試總結(jié)出一些日常編碼的最佳實(shí)踐。之后再圍繞各個容器類型提供的特殊機(jī)能,分享一些編程的小技巧。
當(dāng)我們談?wù)撊萜鲿r,我們在談些什么?
我在前面給了“容器”一個簡單的定義:專門用來裝其他對象的就是容器。但這個定義太寬泛了,無法對我們的日常編程產(chǎn)生什么指導(dǎo)價值。要真正掌握 Python 里的容器,需要分別從兩個層面入手:
-
底層實(shí)現(xiàn): 內(nèi)置容器類型使用了什么數(shù)據(jù)結(jié)構(gòu)?某項操作如何工作?
- 高層抽象: 什么決定了某個對象是不是容器?哪些行為定義了容器?
下面,讓我們一起站在這兩個不同的層面上,重新認(rèn)識容器。
底層看容器
Python 是一門高級編程語言, 它所提供的內(nèi)置容器類型,都是經(jīng)過高度封裝和抽象后的結(jié)果。 和“鏈表”、“紅黑樹”、“哈希表”這些名字相比,所有 Python 內(nèi)建類型的名字,都只描述了這個類型的功能特點(diǎn),其他人完全沒法只通過這些名字了解它們的哪怕一丁點(diǎn)內(nèi)部細(xì)節(jié)。
這是 Python 編程語言的優(yōu)勢之一。相比 C 語言這類更接近計算機(jī)底層的編程語言,Python 重新設(shè)計并實(shí)現(xiàn)了對編程者更友好的內(nèi)置容器類型,屏蔽掉了內(nèi)存管理等額外工作。為我們提供了更好的開發(fā)體驗(yàn)。
但如果這是 Python 語言的優(yōu)勢的話,為什么我們還要費(fèi)勁去了解容器類型的實(shí)現(xiàn)細(xì)節(jié)呢?答案是: 關(guān)注細(xì)節(jié)可以幫助我們編寫出更快的代碼。
如果你依然在編程的世界里迷茫,可以加入我們的Python學(xué)習(xí)扣qun:784758214,看看前輩們是如何學(xué)習(xí)的。交流經(jīng)驗(yàn)。從基礎(chǔ)的python腳本到web開發(fā)、爬蟲、django、數(shù)據(jù)挖掘等,零基礎(chǔ)到項目實(shí)戰(zhàn)的資料都有整理。送給每一位python的小伙伴!分享一些學(xué)習(xí)的方法和需要注意的小細(xì)節(jié),點(diǎn)擊加入我們的 python學(xué)習(xí)者聚集地
寫更快的代碼
1. 避免頻繁擴(kuò)充列表/創(chuàng)建新列表
所有的內(nèi)建容器類型都不限制容量。如果你愿意,你可以把遞增的數(shù)字不斷塞進(jìn)一個空列表,最終撐爆整臺機(jī)器的內(nèi)存。
在 Python 語言的實(shí)現(xiàn)細(xì)節(jié)里,列表的內(nèi)存是按需分配的[注1],當(dāng)某個列表當(dāng)前擁有的內(nèi)存不夠時,便會觸發(fā)內(nèi)存擴(kuò)容邏輯。而分配內(nèi)存是一項昂貴的操作。雖然大部分情況下,它不會對你的程序性能產(chǎn)生什么嚴(yán)重的影響。但是當(dāng)你處理的數(shù)據(jù)量特別大時,很容易因?yàn)閮?nèi)存分配拖累整個程序的性能。
還好,Python 早就意識到了這個問題,并提供了官方的問題解決指引,那就是: “變懶” 。
如何解釋“變懶”?
range()
函數(shù)的進(jìn)化是一個非常好的例子。
在 Python 2 中,如果你調(diào)用
range(100000000)
,需要等待好幾秒才能拿到結(jié)果,因?yàn)樗枰祷匾粋€巨大的列表,花費(fèi)了非常多的時間在內(nèi)存分配與計算上。但在 Python 3 中,同樣的調(diào)用馬上就能拿到結(jié)果。因?yàn)楹瘮?shù)返回的不再是列表,而是一個類型為
range
的懶惰對象,只有在你迭代它、或是對它進(jìn)行切片時,它才會返回真正的數(shù)字給你。
所以說,為了提高性能,內(nèi)建函數(shù)
range
“變懶”了。
而為了避免過于頻繁的內(nèi)存分配,在日常編碼中,我們的函數(shù)同樣也需要變懶,這包括:
-
更多的使用
yield
關(guān)鍵字,返回生成器對象 -
盡量使用生成器表達(dá)式替代列表推導(dǎo)表達(dá)式
-
生成器表達(dá)式:
(iforinrange(100))
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
