python資料結構學習筆記(五)

來源:互聯網
上載者:User

標籤:

 

  • 5 Array-Based Sequence
    • 5.2.1 referential arrays
    • 5.2.2 compact arrays in python
    • array.array
  • 5.3 dynamic arrays and amortization
    • 5.3.1 implementing a dynamic array
  • 5.4 efficiency of python‘s sequence types
  • constant-time operation
    • 字串拼接
  • 5.6 multidimensional data sets
5 Array-Based Sequence5.2.1 referential arrays

數組在記憶體中是連續的地址單元,而且每個單元的大小是相同的。對於python的list來說,裡面可以儲存不同長度的 字串或者其他元素,為了存下最長的那個字串,list必須給每個單元很大的空間,這樣實際上有很多單元只利用 了小部分的儲存,記憶體的利用率很低。實際上,python的list中每個單元只儲存了一個對象的引用,相當於 只儲存了它的地址,這樣所有對象的地址都是統一長度的.list中空的位置的引用指向None對象

5.2.2 compact arrays in python

string是字元數組,這與一般的list不同,list中儲存的是引用,而string中是直接儲存字元,所以可以說是 緊密的的數組。如果string中儲存的是unicode,則每個字元需要2bytes的空間。

與緊密數組相比,普通list需要更多的空間,比如我們想要儲存一百萬個64-bit整數,我們希望每個整數只使用64 bits 來儲存。實際上我們需要在數組中給每個整數儲存一個64位地址的引用,另外每個int類型在python中是14byte,所以 實際上每個整數用了18bytes來儲存。

array.array
from array import arrayprimes = array(‘i‘, [2,3,5,7])

array函數提供緊密數組,其中‘i‘代表integers,array()函數第一個參數是裡面元素的類型。

python中的ctype模組裡提供了類似c語言中的緊密數組。

5.3 dynamic arrays and amortization

建立一個低級的緊密數組的時候,必須聲明數組的大小,因為系統必須給數組分配連續的記憶體空間。

python中的list類則提供了一種可動態擴充的數組,比如可以隨時增加一個元素。在建立一個list的時候,實際上會 比它現在的長度分配多一點空間,用來給新增加的元素。如果原來預留的空間都使用完了,則list會重新向系統申請 新的空間,新的空間又比現在所有儲存的元素預留多一些空間。這種做法就跟螃蟹成長的過程不斷換殼一樣。

len(list)可以擷取當前list裡面存的元素個數,但不是系統真正分配給list的記憶體。sys.getsizeof(list)可以 list真正的bytes。

import sysdata = []for k in range(n):    a = len(data)    b = sys.getsizeof(data)    print "length: {0:3d}; size in types: {1:4d}".format(a,b)    data.append(None)

結果如下:

Length: 0;size in bytes: 72Length: 1;size in bytes: 104Length: 2;size in bytes: 104Length: 3;size in bytes: 104Length: 4;size in bytes: 104Length: 5;size in bytes: 136...

可以發現初始化一個空數組時已經分配了72bytes的空間,後面不斷增加元素之後每次增加32bytes。

5.3.1 implementing a dynamic array

要實現動態增長的數組,我們可以先用一個固定數組a來儲存,當a滿的時候,建立更大的數組b,先使得b[i]=a[i], 然後將a指向b,這時候就可以插入新的元素了。如何確定新數組b的容量比較合適?一種做法是取b的容量剛好是a的2倍

import ctypesclass DynamicArray:    """a dynamic array class like a simplified python list"""    def __init__(self):        self._n = 0        self._capacity = 1        self._A = self._make_array(self._capacity) # low-level array    def __len__(self):        return self._n    def __getitem__(self, k):        if not 0 <= k < self._n:            raise IndexError(‘invalid index‘)        return self._A[k]    def append(self, obj):        if self._n == self._capacity:            self._resize(2 * self._capacity)        self._A[self._n] = obj        self._n += 1    def _resize(self, c):        """resize internal array to capacity c"""        B = self._make_array(c)        for k in range(self._n):            B[k] = self._A[k]            self._A = B            self._capacity = c    def _make_array(self, c):        return (c * ctypes.py_object)()
5.4 efficiency of python‘s sequence types
  • tuple: nonmutating
  • list
constant-time operation

返回序列的長度只需要常數時間,因為序列中維護有這一資訊可以直接返回。同樣是常數時間的有下標訪問data[i]

字串拼接

如要把文檔中的所有字母字元取出組成一個字串, bad code:

letters = ‘‘for c in document:    if c.isalpha():        letters += c

這段代碼是非常低效的。因為string類型是immutable的,每次執行letters += c,都要重新建立一個string,然後 對letters重新賦值,而每次建立一個字串的時間與該字串長度成線性關係,所以總共需要1+2+...+n = O(n*n)的時間。

一種改進的方法是使用一個list代替string拼接,最後再一次性拼接給string,時間是O(n)

temp = []for c in document:    if c.isalpah():        temp.append(c)letters = ‘‘.join(temp)

注意最後一行‘‘.join(temp)只需要n的時間

實際上即使是每次對list進行append操作,雖然攤還時間是O(1),但是仍然可能需要多次動態擴建list,效率不如下面這種 使用comprehension syntax理解性文法。

letters = ‘‘.join([c for c in document if c.isalpha()])

或者連建立list的過程都不需要

letters = ‘‘.join(c for c in document if c.islpha())

因為string是immutable的,所以很多時候要對string進行操作的時候可以先講string轉化為list,然後對其進行修改, 操作完成之後再重新賦值給string。string轉為list方式如list(‘bird‘)可以得到[‘b‘, ‘i‘, ‘r‘, ‘d‘]. 反過來list轉為string則可以通過‘‘.join([‘b‘,‘r‘,‘i‘,‘d‘])

5.6 multidimensional data sets

二維數組通常也叫矩陣。python中可以用嵌套的list來實現。

建立二維矩陣的一個錯誤方法如data = ([0] * c ) * r,因為結果還是一個一維矩陣。

改進一下,用data = [[0] * 3] * 2來建立2 * 3矩陣,得到結果[[0,0,0],[0,0,0]],好像滿足要求。 但實際上這樣做還不行,因為裡面的兩個list實際上指向同一個list,修改其中一個會導致兩個都同時改變。

為了使裡面的每個子list都是相互獨立的,可以使用理解性文法來建立這樣的二維list。 data = [[0] * c for j in range(r)]

python資料結構學習筆記(五)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.