python高階學習(一)資料結構 列表

2021-08-22 04:59:09 字數 3315 閱讀 6098

目錄前言

陣列 列表

列表推導式與高階函式

生成器表示式

當列表不夠用時

雙向佇列 元組

元組與記錄

具名元組nametuple

作為不可變列表

本篇以及接下來的篇章均為《流暢的python》學習筆記,內容主要出自該書,重點偏向於應用

這節主要展示python資料結構的特性,以及使用自帶的collections模組來方便地解決一些實際的問題

collections是python的乙個標準庫,這個模組實現專門的容器資料型別,提供python的通用內建容器,字典,列表,集和元組的替代方法

既然叫做高階學習,那麼列表的基本操作不會再次描述

現有乙個需求,篩選出列表中大於0的元素

最簡單的想法當然是遍歷一遍啦

lis = [-2,1,4,6,-4,0,2,5]

result =

for i in lis:

if i > 0:

print(result)

也可以用列表推導式,列表推導式其實就是一種生成列表的快捷方法,可以增加**可讀性,for in表示迭代的列表,if後面寫上條件

lis = [-2,1,4,6,-4,0,2,5]

[x for x in lis if x>0]

用高階函式也是可以的

lis = [-2,1,4,6,-4,0,2,5]

list(filter(lambda x: x>0, lis))

那麼用列表推導式和高階函式哪乙個快一點呢?答案是不一定,一般用列表推導式,不過它們倆都比迭代更好。

字典,集合資料結構和列表一樣都有相應的推導式,在需要的時候也可以使用。

生成器表示式構建生成器,可以通過迭代逐個構建元素,所以使用生成器可以節省記憶體。

collections包中實現的雙向佇列,是乙個執行緒安全、可以快速從兩端新增和而刪除元素的資料型別。

from collections import deque

dq = deque(range(10))

# deque([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

dq.popleft()

# deque([1, 2, 3, 4, 5, 6, 7, 8, 9])

# deque([10, 1, 2, 3, 4, 5, 6, 7, 8, 9])

雙向佇列只對佇列兩端的操作做了優化,相應的,佇列中間的元素操作會慢一些。

元組在python中一般都是用作不可變列表,但是它還有另乙個功能,就是作為無名字段的記錄。

在元組用作資料記錄時,元組中每個元素都存放了記錄中乙個欄位的資料,外加上這個欄位的位置。作為記錄來說,元組的位置資訊就變得非常重要了。

我們可以用下面的方式來記錄乙個使用者的id,name,email和password

user1 = ('1', 'alice', '[email protected]', '123456')
是不是很像乙個資料庫的記錄了呢? 

並且python的拆包功能能夠讓元組更加方便地當成記錄來使用

in [3]: id, name, email, password = ('2', 'tom', '[email protected]', '123456')

in [4]: user2 = (id, name, email, password)

in [2]: user[1]

out[2]: 'alice'

可以看到,元組可以採用數字來獲取元組中某個欄位的值,但是這樣子寫明顯存在很多的問題,一旦欄位一多,**裡全是各種數字檢索值,無法一眼看出這個引用所代表的含義,這樣的程式就很難維護和閱讀。

一般可以想到的方法是,把字段的名稱以及對應的字段位置用常量的方式來定義

id = 0

name = 1

email = 2

password = 3

這樣一來如果要取值的話只需:

in [2]: user[name]

out[2]: 'alice'

可讀性是不是好點啦?

不過我們也可以使用具名元組nametuple來解決問題,它可以構建乙個帶有欄位名的元組和乙個有名字的類

使用方法:

collections.namedtuple(typename, field_names, *, verbose=false, rename=false, module=none)

第乙個引數設定這個類的名字,第二個引數可以傳入欄位名的列表

in [5]: from collections import namedtuple

in [6]: user = namedtuple('user', ['id', 'name', 'email', 'password'])

可以看到,nametuple就是乙個工廠函式,作用就相當於建立乙個類

這種做法是不是和構建乙個類來存放記錄資料差不多?的確,不過由nametuple構建的類的例項比普通類構建的例項消耗的記憶體更小,因為普通的類需要使用__dict__來存放類例項的屬性,而nametuple構建的類則不需要,且例項所消耗的記憶體和元組是一樣的,因為欄位名是存放在對應的類裡面。

我們可以使用類的建立方式來建立一組資料

in [7]: u1 = user('3', 'bob', '[email protected]', '123456')

in [8]: u1

out[8]: user(id='3', name='bob', email='[email protected]', password='123456')

同時,我們可以使用獲取類屬性的方式來獲取資料,這樣使用非常的方便

in [9]: u1.id

out[9]: '3'

in [10]: u1.email

out[10]: '[email protected]'

另外,我們可以看到,建立出來的類也是tuple的子類,也就是說,任何可以使用元組的地方,我們也可以使用nametuple來代替

in [11]: isinstance(u1 ,tuple)

out[11]: true

元組當然也可以當做不可變列表來用,除了增減元素的方法外,元組支援列表的其他所有方法。

一 資料結構

char cs new char char cs1 new char 4 cs1 0 a 注意 注意陣列下標越界 char cs new char system.out.println cs 4 特點 1.記憶體位址連續,使用之前必須指定陣列長度 2.可以通過下標訪問的方式訪問成員,查詢效率高 3....

資料結構(一 資料結構基礎

程式 資料結構 演算法 越工作越發現業務 是很容易的,框架也是舊瓶裝新水,大體差不多。那麼好的 的區分在於演算法,效能這些的差距。而資料結構是演算法實現的基礎,演算法總是要依賴某種資料結構來實現的。好久沒有仔細看資料結構了,最近被頻繁的演算法,奈何我資料結構基礎不好。決定好好複習一遍,並輸出乙份文件...

redis 學習之一(資料結構)

儲存物件的兩種方式 儲存序列化之後的物件 jedis.set user liudehua obj getbytes getbytesbyproduct person user liudehua obj getbytes fasdf 不能用這種形式 byte productbytes jedis.ge...