3內置數據結構_數值_列表

內置數據結構

 

幫助:

手冊中找關鍵字;

help(keyword)keyword可以是變量、對象、類名、函數名、方法名;

 

分類:

數值型:int,float,complex,bool

sequence序列對象:str,list,tuple

鍵值對:set集合(約定set爲集,collection爲集合類型),dict字典;

 

 

 

數值型:

int,float,complex,book都是class1,5,0,2+3j都是對象(即實例);

intpython3int就是長整型,且沒有大小限制(沒有上限,指進程尋址的最大內存區域),受制於內存區域的大小;

float,由整數部分和小數部分組成,支持十進制和科學計數法表示,只有雙精度型,通常浮點數比較時用<,>,不能用==(注:浮點數並不能完全準確的表達我們指定的小數,只能說近似表達);

complex,複數,由實數部分和虛數部分組成,實數部分和虛數部分都是浮點數,如3+4.2j

boolint的子類(類似哺乳類下的人類),僅有2個實例True(對應1),False(對應0),可以和整數直接運算;

 

類型轉換:

int(x),返回一個整數;

float(x),返回一個浮點數;

complex(x)complex(x,y),返回一個複數;

bool(x),返回布爾值;

 

數字的處理函數:

round(),不是四捨五入,是四捨六入五取偶,銀行家算法,其它語言的round()也一樣;

math.floor(),地板,向下取整;

math.ceil(),天花板,向上取整;   #django.core.paginator.PaginatorPaginator.num_pages用到

int(),取整數部分,和//整除一樣;

min()

max()

pow(),等於x**6

math.sqrt(),開平方;

bin(),進制函數,返回值是字符串;

oct(),進制函數,返回值是字符串;

hex(),進制函數,返回值是字符串;

math.pi,取PI

math.e,自如常數;

 

例:

In [1]: round(1.4)

Out[1]: 1

In [2]: round(1.5)

Out[2]: 2

In [3]: round(1.6)

Out[3]: 2

In [4]: round(2.6)

Out[4]: 3

In [5]: round(2.5)   #四捨六入五取偶

Out[5]: 2

In [6]: import math

In [7]: math.floor(2.5)

Out[7]: 2

In [8]: math.ceil(2.5)

Out[8]: 3

 

類型判斷:

type(obj),返回類型,而不是字符串;

isinstance(obj,class_or_tuple),返回布爾值;

 

例:

In [9]: a=1

In [10]: type(a)

Out[10]: int

In [11]: type(type(a))

Out[11]: type

In [12]: type(a)==int

Out[12]: True

In [13]: isinstance(a,int)   #類繼承時使用

Out[13]: True

In [14]: type(1+True)

Out[14]: int

In [15]: type(1+True+2.0)   #有隱式轉換,intfloat都是數值型,可理解爲這倆是表親;

Out[15]: float

 

 

 

list

一個隊列,一個排列整齊的隊伍(有序);

列表內的個體稱作元素(itemelement),由若干元素組成列表;

元素可以是任意對象(數字、字符串、對象、列表);

列表內元素有順序,可以使用索引;

線性的數據結構;

使用[]表示;

列表是可變的;

 

list列表、鏈表、queue隊列、stack棧的差異:

list,有序的整齊排列;

1.jpg

鏈表(元素手拉手在一起,不是網狀,在內存中零散的存放,不能用索引);

2.jpg

queue(先進先出或後進先出,可用list模擬queue);

stack(壓棧,後進先出,撂盤子);

3.jpg

 

注:

賦值即定義(動態語言與靜態語言的差別);

 

list定義,初始化:

list()new empty list

list(iterable)new list initialized from iterable's item,如lst=list(5)不可以,必須是可迭代對象,list()裏要麼放可迭代對象,要麼什麼都不放;

列表不能一開始就定義大小;

 

例:

In [16]: lst=list()   #工廠方法定義

In [17]: lst=[]

In [18]: lst=[2,6,9,'ab',None]   #通常用此種,定義和初始化一起搞

In [19]: lst=list(range(5))

In [21]: lst

Out[21]: [0, 1, 2, 3, 4]

In [22]: _   #僅在ipython中使用此變量,返回上一次輸出

Out[22]: [0, 1, 2, 3, 4]

 

list索引訪問:

索引也叫下標,列表通過索引訪問,list[index],使用[]訪問;

正索引,從左至右,從0開始,爲列表中的第一個元素編號;

負索引,從右至左,從-1開始;

正負索引不可以超界,否則引發異常IndexError

爲理解方便,可認爲列表是從左至右排列的,左邊是頭部,右邊是尾部,左邊是下界,右邊是上界;

 

list查詢:

index(value,[start,[stop]]),通過value,從指定區間查找列表內的元素是否匹配;匹配第一個就立即返回索引;從左至右,從右至左,返回的索引值是不一樣的,通常從右至左找更快更便利,如在給定路徑中找文件名;匹配不到,拋出異常ValueError

count(value),返回列表中匹配value的次數;

 

時間複雜度:

O(1),性能最好;

O(n),O(n**2),隨着列表數據規模的增大而效率下降;

index()count()都是O(n)

如何返回列表元素的個數?如何遍歷?如何設計高效?len(lst)len()是公共內置函數,O(1),增刪list元素時記錄着該list的類似元數據信息;

 

空間複雜度:生產中,尤其是vm中要考慮;

 

list元素修改:

lst[index]=value,索引訪問修改,索引不要超界;

 

list增加插入元素:

append(object)-->None,列表尾部追加元素,返回None;返回None就意味着沒有新的list產生,就地修改;時間複雜度O(1)

insert(index,object)-->None,在指定的index處插入元素object;返回None,就地修改;時間複雜度O(1),該方法少用,若在頭部或中間插入,整個內存中的元素需移動;

索引能超上下界嗎?超越上界,尾部追加,超越下界,頭部追加;

extend(iterable)-->None,將可迭代的元素追加進來,返回None,就地修改;

+-->list,連接操作,將兩個list連接起來,產生新的list,原list不變;本質上調用的是__add__()方法;

*-->list,重複操作,將本list元素重複n次,返回新的list

 

注:

返回若不是None,將有特殊的編程方式;

list不適用insert元素,頭或中間插入時需要挪動,鏈表適合insert

 

list刪除元素:

remove(value)-->None從左至右查找第一個匹配value的值,移除該元素返回None,就地修改;效率?不高;

pop([index])-->item,若不指定index就從list尾部彈出一個元素;指定index,就從索引處彈出指定元素;索引超界,拋出IndexError;效率?移除尾部元素效率高,不是尾部不要用;指定索引的時間複雜度?不指定索引的時間複雜度?

clear()-->None,清除列表的元素,剩下一個空列表;元素量大時會引起GC

 

list其它操作:

reverse()-->None,將列表元素反轉,返回None,就地修改,少用;

sort(key=None,reverse=False)-->None,對列表元素進行排序,就地修改,默認升序,少用;reverseTrue,反轉,降序;key(高階函數)指定一個函數,用於自定義排序;

innot in,返回bool型;

 

例:

In [23]: lst=[1,2,3,4]

In [24]: lst.sort(reverse=True)   #注意關鍵字參數,就地修改

In [25]: lst

Out[25]: [4, 3, 2, 1]

In [26]: lst.append('a')

In [27]: lst.sort(key=str)   #把每個元素都轉爲str,按ASCII碼排序

In [28]: lst

Out[28]: [1, 2, 3, 4, 'a']

In [29]: lst.sort(key=str,reverse=True)

In [30]: lst

Out[30]: ['a', 4, 3, 2, 1]

 

列表複製(深淺拷貝):

在構造嵌套結構的列表時要注意;

==是值比較,內容是否相同;

is是比較內存地址,相當於先取id()再比較;

 

copy()-->listshadow copy,影子拷貝,淺拷貝,返回一個新列表,遇到引用類型,只是複製了一個引用,列表如果有嵌套則拷貝的是嵌套列表的內存地址,內層相當於在引用;

 

深拷貝,copy模塊提供了deepcopy()copy.deepcopy()

 

 

例:

In [35]: lst0=list(range(4))

In [36]: lst1=list(range(4))

In [37]: lst0==lst1   #lst[0] is lst[1]結果爲False

Out[37]: True

In [38]: lst2=lst0

In [39]: lst2[2]=10

In [42]: lst2==lst1

Out[42]: False

In [44]: lst0

Out[44]: [0, 1, 10, 3]

In [45]: lst1

Out[45]: [0, 1, 2, 3]

In [46]: lst2

Out[46]: [0, 1, 10, 3]

In [47]: id(lst0)   #lst2引用lst0,這倆指向同一個內存地址

Out[47]: 139655179771656

In [48]: id(lst2)

Out[48]: 139655179771656

 

例:

In [50]: lst3=list(range(4))

In [51]: lst4=lst3.copy()

In [52]: lst3==lst4

Out[52]: True

In [53]: lst3 is lst4

Out[53]: False

In [54]: lst3[2]=10

In [55]: lst3==lst4

Out[55]: False

 

例:

In [71]: lst5=[1,[2,3,4],5]

In [72]: lst6=lst5.copy()

In [73]: lst5==lst6

Out[73]: True

In [74]: lst5[1][1]=8

In [75]: lst5==lst6   #注意,返回Truelst6lst5的拷貝,對於嵌套結構只copy()了引用

Out[75]: True

In [76]: lst5 is lst6

Out[76]: False

In [77]: lst5

Out[77]: [1, [2, 8, 4], 5]

In [78]: lst6

Out[78]: [1, [2, 8, 4], 5]

4.jpg

 

例:

In [1]: import copy

In [2]: lst0=[1,[2,3,4],5]

In [3]: lst1=copy.deepcopy(lst0)

In [4]: lst1[1][1]=8

In [5]: lst0==lst1

Out[5]: False

In [6]: lst0 is lst1

Out[6]: False

 

 

 

隨機數:

random模塊;

random.randint(a,b),返回[a,b]之間的整數,兩邊都是閉區間(不同於range(a,b)[a,b)前包後不包);

random.choice(seq),從非空序列的元素中隨機挑選一個元素,如random.choice(range(10)),從0-9中挑選一個整數,random.choice([1,3,5,7])

random.randrange([start,]stop[,step]),同range(),從指定範圍內,按指定基數遞增的集合中獲取一個隨機數,基數缺省值爲1,如random.randrange(1,7,2),返回1,3,5中的一個;

random.shuffle(list)-->None,就地打亂列表元素;

 

 

 

測試效率:

#作性能測試時把print()語句註釋掉,否則影響較大;

import datetime

start = datetime.datetime.now()

code segment

stop = datetime.datetime.now()

delta =(stop-start).total_seconds()

print(delta)


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章