python字典内存分析_python--序列,字符串,列表,元组,字典,集合内存分析
一,什么是序列、
序列是一種數據存儲方式,用來存儲一系列的數據,在內存(堆內存)中,序列是一塊用來存放多個值的連續的內存空間,其存儲的值為所指向對象的地址。比如說a = [ 10 , 20 , 30 , 40? ?]在內存中實際是按照以下方式存儲的。下圖中序列存儲的是整數對象的地址,而不是整數對象的值。python中常用的序列結構有:字符串,列表,元組,字典,集合
列表:
一,什么是列表?
是一種用來存儲任意數目,任意類型的數據集合。
二,列表的底層原理是什么?
參照上圖
三,列表的三種創建方式
1.基本語法? [ ]? 創建
a = [ 1, 2 , "abc" ]
a = [ ]
2,list()創建:使用list()可以將任何可迭代對象轉化為列表
a = list( )
a = list(range(10))
注意:range的語法格式: range([start],end,[step])
start:可選,表示起始數字,默認是0
end:必選,表示結尾數字
step:可選,表示步長,默認是1,可正可負
python3中range()返回的是一個range對象,而不是列表,我們需要通過list()方法將其轉換為列表對象
3.推導式生成列表
a = [ x*2 for x in range( 5 )? if x%3==0 ]
第一步:range(5)為,[ 0,1,2,3,4 ]
第二步:每個x分別乘2。[ 0,2,4,6,8 ]
第三步:判斷是否為3的倍數。[ 6 ]
四,對列表的操作(添加元素,刪除元素,訪問元素,切片,排序)
添加元素(5種)
當列表增加和刪除元素時,列表會自動進行內存管理,大大減少程序員的負擔。但這個特點涉及列表元素的大量移動,效率較低。(當在中間插入或刪除元素時,實質上是對數組的拷貝,故而效率較低)除非必要,我們一般只在列表的尾部添加元素或者刪除元素,這會大大提高列表的操作效率。
1. append():原地修改列表對象,是真正的在列表尾部添加新的元素,速度最快,推薦使用。
2. +運算符操作:并不是真正的尾部添加元素,而是創建新的列表對象;將原列表的元素和新列表的元素依次復制到新的列表對象中。這樣會涉及大量的復制操作,對于操作大量元素不建議使用
a?=?[20,40]
a?=?a?+?[50]
3.extend():將目標列表的所有元素添加到本列表的尾部,屬于原地操作,不創建新的列表對象
a?=?[20,40]
a.extend([50,60])
4.insert():使用insert()方法可以將制定元素插入到列表對象的任意指定位置。這樣會讓插入位置后面的所有的元素進行移動,會影響處理速度。涉及大量元素時,盡量避免使用。類似發生這種移動的函數還有:remove(),pop(),del(),它們在刪除非尾部元素時也會發生操作位置后面元素的移動。
a?=?[20,40]
a.insert(索引,元素)
5.乘法擴展:使用乘法擴展列表,生成一個新列表,新列表元素由原列表多次重復。適用乘法操作的還有:字符串,元組
a?=?[20,40]
b?=?a*3
刪除元素(3種,其內存原理參照上文insert()方法)
1.del刪除:刪除列表指定位置的元素()
a?=?[10,20,30]
del?a[索引]
2.pop():刪除并返回指定位置元素,如果未指定位置則默認操作列表最后一個元素
a?=?[10,20,30]
b?=?a.pop(索引)
3.remove():刪除首次出現的指定元素,若不存在該元素則拋出異常。
a?=?[10,20,30]
a.remove(20)
訪問元素(5種)
1.通過索引直接訪問元素:可以通過索引直接訪問元素,索引的區間在 [ 0 , 列表長度-1]這個范圍。超過這個范圍會拋出異常。
2.index():可以獲取指定元素首次出現的索引位置并返回。語法:index(value , [ start , [ end] ] )。其中,start和end指定了搜索范圍.
a?=?[10,20,30]
b = a.index(20,1,2)
3.count():返回指定元素在列表中出現的次數
4.len()返回列表長度
5.成員資格判斷:判斷列表中是否存在指定的元素,我們可以使用count()方法,返回0表示不存在,返回大于0表示存在。另外,一般可以使用in關鍵字來判斷,直接返回true或false
a?=?[10,20,30]
20?in?a
切片
切片適用于列表,元組,字符串等等(之前講的爛大街了,不講了)
注意一點:切片操作時,起始偏移量和終止偏移量不在[0 , 字符串長度-1]這個范圍,也不會報錯。起始偏移量小于0則會被當作0,終止偏移量大于“長度-1”會被當作-1
排序
sort():修改原列表,不建新列表。默認升序排列,降序reverse=true
sorted():不修改原列表,構建新列表
reverse():修改原列表,反向列表中元素
reversed():不對原列表做任何修改,只是返回一個逆序排列的迭代器對象。需要用list()方法進行處理,也可以用迭代器__next__方法逐個迭代
其他內置函數:
max(a),min(a),sum(a)
列表的拷貝
淺拷貝和深拷貝
元組
列表屬于可變序列,可以任意修改列表中的元素。元組屬于不可變序列,不能修改元組中的元素。因此,元組沒有增加元素,修改元素,刪除元素相關的方法。
元組支持如下操作:1.索引訪問,2.切片操作,3.連接操作,4.成員關系操作,5.比較運算操作,6.計數:len(),max(),min(),sum()
元組的創建
1.通過()創建元組,小括號可以省略。如果元組只有一個元素,則必須后面加上逗號。這是因為解釋器會把(1)解釋為整數1,(1,)解釋為元組
a?=?(10,20,30)或者a?=?10,20,30
2.tuple(可迭代對象)創建元組
總結:tuple()可以接收列表,字符串,其他序列類型,迭代器等生成元組
list()可以接收元組,字符串,其他序列類型,迭代器等生成列表
3.zip(列表1,列表2,...)將多個列表對應位置的元素組合為元組,并返回這個zip對象(zip對象需要list()或者tuple()來進行處理)
4.生成器推導式創建元組:
從形式上來看,生成器推導式與列表推導式類似,只是生成器推導式使用小括號。列表推導式直接生成列表對象,生成器推導式生成的不是列表也不是元組,而是一個生成器對象。
可以通過生成器對象,轉化成列表或者元組。也可以使用生成器對象的__next__()方法進行遍歷,或者直接作為迭代器對象進行使用。不管用什么方式使用,元素訪問結束后,如果需要重新訪問其中的元素,必須重新創建該生成器對象。
元組的訪問
元組的元素訪問和列表一樣,只不過返回的對象仍然是元組
元組的排序
列表關于排序的方法list.sorted()是修改列表對象,元組沒有該方法。如果需要對元組進行排序,只能使用內置函數sorted(tupleObj),并生成新的列表對象
元組的總結
1.元組的核心特點是:不可變序列。
2.元組的訪問和處理速度比列表快
3.與整數和字符串一樣,元組可以作為字典的鍵,列表則永遠不能作為字典的鍵使用。
字典
字典的創建
1.通過{},dict()來創建字典對象
a?=?{'name':'wbh','age':20,'school':'xd'}
b?=?dict('name'='wbh','age'=20,'school'='xd')
c?=?dict([('name','wbh'),('age',20)])
d?=?{}
e?=?dict()
2.通過zip()創建
f?=?dict(zip(key_list,value_list))
3.通過fromkeys創建值為空的字典
g?=?dict.fromkeys([key1,key2,key3])? #值為none
字典元素的訪問
1,通過[ 鍵 ]獲得“值”。若值不存在,則拋出異常
2,通過get(鍵)方法獲得“值”。推薦使用:優點:指定鍵不存在,則返回none;也可以設置鍵不存在時默認返回的對象
3,列出所有的鍵值對:a.items()
4,列出所有的鍵:a.keys()
5,列出所有的值:a.values()
6,len():輸出鍵值對的個數
7,檢測一個“鍵”是否在字典中:“鍵”? in? a
字典元素的添加,修改,刪除
1,給字典新增“鍵值對”。如果“鍵”已經存在,則覆蓋舊的鍵值對;如果‘’鍵“不存在,則新增”鍵值對“。
a['鍵']?=?值
2,使用update()將新字典中所有鍵值對全部添加到舊的字典對象上。如果key有重復,則直接覆蓋
a.update(b)
3,字典中元素的刪除,可以使用del()方法;或者clear()刪除所有的鍵值對;pop(0刪除指定鍵值對,并返回對應的”值對象“
del(a['name'])
a.clear()
b?=?a.pop('age')
4,popitem():隨即刪除和返回該鍵值對。字典是”無需可變序列“,因此沒有第一個元素,最后一個元素的概念(可以類比想想集合);popitem()彈出隨機的項,因為字典并沒有”最后的元素“或者其他有關順序的概。若想一個接一個地移除并處理項,這個方法就非常有效
字典核心底層原理
字典對象地核心是散列表。散列表里是一個稀疏數組(總是有空白元素的數組),數組的每個單元叫做bucket。每個bucket由兩部分:一個是鍵對象的引用,一個是值對象的引用。由于所有的bucket結構和大小一致,所以可以通過偏移量來讀取指定bucket。
將一個鍵值對放進字典的底層過程
假設字典對象a創建完成后,數組長度為8:
我們如果要把“name” = “wbh”這個鍵值對放到對應的字典對象a中,首先第一步需要計算“name”的散列值。python中可以通過hash()來計算。由于數組長度為8,我們可以拿計算出的散列值的最右邊3位數字作為偏移量,查看偏移量對應的bucket是否為空。如果為空,則將鍵值對放進去。如果不為空,則依次取右邊3位作為偏移量。當數組被填滿至一定程度時,會自動進行擴容。
根據鍵查找“鍵值對”的底層過程
當我們調用a.get('name'),時。程序第一步會先計算“name”對象的散列值。和存儲的底層流程算法一致,也是依次取散列值的不同位置的數字。假設數組長度為8,我們可以拿計算出的散列值的最右邊3位數字作為偏移量。查看偏移量對應的bucket是否為空。如果為空,則返回None。如果不為空,則將這個bucket的鍵對象計算散列值,和我們的散列值進行比較,如果相等,則將對應的“值對象”返回。如果不相等,則再依次取其他幾位數字,重新計算偏移量。依次取完后仍然沒有找到,則返回None
集合
集合的創建和刪除
集合相關操作
總結
以上是生活随笔為你收集整理的python字典内存分析_python--序列,字符串,列表,元组,字典,集合内存分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python写入excel数据教程_py
- 下一篇: websocket python爬虫_p