1. 程式人生 > 其它 >python中除list,dict,str外的其它序列資料結構

python中除list,dict,str外的其它序列資料結構

目錄

陣列

這裡是指python標準庫中的陣列,即array.array,而非numpy陣列。

  • 如果想要一個只包含數字的列表,那麼陣列更合適。陣列支援所有跟可變序列相關的操作,包括.pop、.insert、.extend。

  • 陣列提供從檔案讀取和存入檔案的方法,即.frombytes和.tofile。

  • 建立時狐族需要使用型別碼,該型別碼用來表示再底層的C語言應該存放怎樣的資料型別。比如array('b'),型別碼為'b',此時建立的陣列只能存放一個位元組大小的整數。因為'b'代表有符號的字元,大小範圍為-128到127。

  • 建立包含1000萬個浮點數的陣列,並儲存到檔案,從檔案中載入。如下邊例子。將浮點數寫入讀出二進位制檔案都要比文字檔案快很多倍,且二進位制檔案大小更小。

    from array import array
    from random import random
    
    floats = array('d', (random() for i in range(10**2))) # 生成器表示式可以用於生成任意序列型別,'d'表示是雙精度浮點數物件,跟python內建型別不同,array.array是需要指定數值精度的
    print(floats[-1]) # 檢視陣列中最後一個元素
    fp = open('floats.bin', 'wb') # 以二進位制可寫的方式開啟一個檔案,如果檔案不存在,則建立該檔案
    floats.tofile(fp) # 用.tofile方法把陣列中的內容寫入到二進位制檔案floats.bin中
    fp.close() # 關閉檔案
    floats2 = array('d') # 再建立一個儲存雙精度浮點數的陣列物件
    fp = open('floats.bin', 'rb') # 開啟上邊關閉的檔案
    floats2.fromfile(fp, 10**2) # 用.fromfile方法從開啟的檔案中讀取10**2個元素到新建的陣列
    fp.close() # 關閉檔案
    print(floats2[-1]) # 檢視第二個陣列的最後一個元素
    print(floats2 == floats) # 判斷兩個陣列是否相等
    
  • 除了array.array的tofile和fromfile方法外,pickle模組的dump方法也可以將物件儲存到檔案(也叫序列化),或者load方法從檔案載入到物件(也叫反序列化)。pickle是python專用,檔案字尾為.pkl。可以選擇儲存成文字檔案或二進位制檔案。

  • python陣列array.array非常類似C語言中的陣列,要提供資料型別。

  • array陣列不支援list.sort這種原地排序方法,要先用sorted生成一個排序好的新陣列,然後讓原陣列名關聯到此新陣列。
    a = array.array(a.typecode, sorted(a))

記憶體檢視memoryview

memoryview是一個內建類,跟torch中的view方法有類似之處,就是從不同角度看待同一塊記憶體區域的資料。

from array import array
from random import random
 
numbers = array('h', [i for i in range(-2, 3)]) # 列表推導式生成陣列,陣列元素是十六進位制整數
memv = memoryview(numbers) # 從記憶體角度看待該陣列
print(len(memv), memv.tolist()) # 打印出陣列長度於具體值,可以看出跟number一樣
print(memv[0]) # 陣列的第一個元素就是現在記憶體檢視的第一個元素
memv_oct = memv.cast('B') # memv.cast型別強制轉換,改成以無符號字元的角度來看待numbers陣列的那一塊記憶體
print(len(memv_oct), memv_oct.tolist()) # 因為一個無符號字元佔八個位元組,原先十六進位制中的一個數字被拆分成了兩個,因此記憶體檢視長度加倍
memv_oct[5] = 4 # 改變記憶體檢視的某個索引的值,可以影響到原陣列,因為是共享記憶體的。
print(numbers)

numpy和scipy

  • numpy實現了多維同質陣列和矩陣,scipy是基於numpy的庫。
  • numpy也可以輕易實現陣列物件與檔案的互動。numpy.save()用於將一個多維陣列儲存到一個二進位制檔案中。

雙向佇列和其它形式的佇列

python中列表可以當作棧或者佇列使用

  • 當作佇列使用時,.append()插入元素,.pop(0)刪除元素,模擬先進先出
  • 當作棧使用時,.append()插入元素,.pop(l.size()-1)刪除元素,模擬後進先出。
  • 缺點是刪除列表第一個元素之類的操作會移動列表中所有元素,非常耗時。

collections.deque雙端佇列

collections.deque是一個執行緒安全的雙端佇列。
使用格式為:

from collections import deque
dp = deque(range(10), maxlen=10)
dp.rotate(3)
dp.rotate(-4)
dp.appendleft(-1)
dp.extend([11, 22, 33])
dp.extendleft([44, 55, 66])
  • 構造雙端佇列時有一個可選引數maxlen,代表這個佇列可以容納的元素數量,一旦設定不可更改。如果新增元素超過容量,則會自動刪除一部分元素,左邊插入則右邊刪除,右邊插入則左邊刪除。

queue

提供了執行緒安全類Queue、LifoQueue和PriorityQueue。

multiprocessing

這個包實現了自己的Queue,與queue.Queue類似,是設計給程序間通訊用的。還有一個專門的multiprocessing.JoinableQueue型別。

asyncio

python3.4新提供的包,有Queue,LifoQueue,PriorityQueue,JoinableQueue,為非同步管理提供了專門的便利。

heapq

沒有佇列類,但是提供了heappush和heappop方法,可以把可變序列當佇列或優先佇列用。