- 1、Python中dict為什麼比list浪費內存?求大神,感激不盡!!
- 2、python dict字典類型內存佔用問題
- 3、python dict 實現原理 2019-04-17
- 4、python的內存問題該這麼解決?
不知道你對c有沒有了解,python解釋器就是基於c寫的,這個兩個數據結構應該對應c的哈希表和數組。
因為哈希表需要額外內存記錄映射關係,而數組只需要通過索引就能計算出下一個節點的位置,所以哈希表佔用的內存比數組大,也就是dict比list佔用的內存大些。
不過使用python說明對性能沒有極端的要求,具體使用哪個主要還是要看項目的需要。
如果解決了您的問題請採納!
如果未解決請繼續追問
應該吧文件切開來讀,一次讀一部分,read()括號里寫讀取大小。否則一次性開到內存去,開銷灰常大,灰常不合算
dict對象是Python中一個原始的數據類型,按照鍵值對的方式存儲,中文名為字典,其通過鍵名查找對應的值有很高的效率,時間複雜度在常數級別O(1)。Python dict的底層是依靠哈希表(Hash Table)進行實現的,使用開放地址法解決衝突。所以其查找的時間複雜度會是O(1),why?
哈希表是key-value類型的數據結構,通過關鍵碼值直接進行訪問。通過散列函數進行鍵和數組的下標映射從而決定該鍵值應該放在哪個位置,哈希表可以理解為一個鍵值需要按一定規則存放的數組,而哈希函數就是這個規則。
算法中時間和空間是不能兼得的,哈希表就是一種用合理的時間消耗去減少大量空間消耗的操作,這取決於具體的功能要求。
創建一個數組,數組下標是索引號,數組中的值是要獲得的數據,這樣只需要O(1)的時間複雜度就可以完成操作,但是擴展性不強,有以下兩個方面的考慮:
-1- 新添加的元素超出數組索引範圍,這就需要重新申請數組進行遷移操作。
-2- 假設一種極端的情況:只存在兩個元素,索引號分別是1和100000000001,按照先前的設計思路,會浪費很大的存儲空間。
會不會存在一個方法,為已有的索引創建新的索引,通過壓縮位數,讓新索引可以和原有的大範圍的稀疏索引進行一一對應,新索引所需要的存儲空間要大大減小,這就是哈希思想。
上面的例子中哈希函數的設計很隨意,但是從這個例子中我們也可以得到信息:
哈希函數就是一個映射,因此哈希函數的設定很靈活,只要使得任何關鍵字由此所得的哈希函數值都落在表長允許的範圍之內即可;
因為新的索引對舊的索引進行了空間上的壓縮,所以不可能所有的輸入都只對應唯一一個輸出,也就是哈希函數式有可能發生衝突的,哈希函數不可能做成一對一的映射關係,其本質是一個多對一的映射。
直接定址法:很容易理解,key=Value+C; 這個「C」是常量。Value+C其實就是一個簡單的哈希函數。
除法取余法: 很容易理解, key=value%C;解釋同上。
數字分析法:這種蠻有意思,比如有一組value1=112233,value2=112633,value3=119033,針對這樣的數我們分析數中間兩個數比較波動,其他數不變。那麼我們取key的值就可以是key1=22,key2=26,key3=90。
平方取中法。此處忽略,見名識意。
摺疊法:這種蠻有意思,比如value=135790,要求key是2位數的散列值。那麼我們將value變為13+57+90=160,然後去掉高位「1」,此時key=60,哈哈,這就是他們的哈希關係,這樣做的目的就是key與每一位value都相關,來做到「散列地址」儘可能分散的目地。
當兩個不同的數據元素的哈希值相同時,就會發生衝突。解決衝突常用的手法有2種:
開放地址法:
如果兩個數據元素的哈希值相同,則在哈希表中為後插入的數據元素另外選擇一個表項。當程序查找哈希表時,如果沒有在第一個對應的哈希表項中找到符合查找要求的數據元素,程序就會繼續往後查找,直到找到一個符合查找要求的數據元素,或者遇到一個空的表項。
鏈接法:
將哈希值相同的數據元素存放在一個鏈表中,在查找哈希表的過程中,當查找到這個鏈表時,必須採用線性查找方法。
python的dict採用了哈希表,最低能在 O(1)時間內完成搜索,在發生哈希衝突的時候採用的是開放尋址法。java的HashMap也是採用了哈希表實現,但是在發生哈希衝突的時候採用的是鏈接法。
1.沒有開gc,或者gc設為debug狀態,導致交叉引用沒有被回收調
2.如果一個數據在邏輯上不應該存在,但是因為代碼上沒有做相關清除操作,導致他還存在,也是一種泄漏
舉個栗子,例如我要記錄最近50天的某個基金的日化收益率,定義一個全局的字典global_dict,運行了一個腳本進行計算,沒10分鐘算一次,但是我沒有進行clear操作,每次的計算只是單純的賦值dict[date] = rate,按理來說dict[“五十天前”]的收益率都是不需要的,就是一種泄漏。
3.這種情況出現在python3.4之前,因為3.4已經修復了,是這樣的,如果一個類定義了__del__,並且該類存在循環引用的情況,這時候gc就會把這個類放在gc.garbage當中,不會去做回收,可以說是跳出了分代回收的機制,但是3.4之後的版本就沒有這種情況,會把他回收調。
原創文章,作者:WMITM,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/126235.html