天天看點

剛才,我發現了Python強大的内置子產品collections

1. 子產品說明

collections 是 Python 的一個内置子產品,所謂内置子產品的意思是指 Python 内部封裝好的子產品,無需安裝即可直接使用。

  • collections 包含了一些特殊的容器,針對 Python 内置的容器,例如:list、dict、set、tuple,提供了另一種選擇;
  • namedtuple:可以建立包含名稱的 tuple;
  • deque:類似于 list 的容器,可以快速的在隊列頭部和尾部添加、删除元素;
  • OrderedDict:dict的子類,可以記住元素的添加順序;
  • defaultdict:dict的子類,可以調用提供預設值的函數;
  • Counter:dict的子類,計算可hash的對象;

2. 實戰代碼

(1). testNamedTuple函數

Python 提供了很多非常好用的基本類型,比如不可變類型 tuple,我們可以輕松地用它來表示一個二進制向量。

namedtuple 是一個函數,它用來建立一個自定義的 tuple 對象,并且規定了 tuple 元素的個數,并可以用屬性而不是索引來引用 tuple 的某個元素。

如此一來,我們用 namedtuple 可以很友善地定義一種資料類型,它具備 tuple 的不變性,又可以根據屬性來引用,使用十分友善。

本示例中我們使用了一個三維坐标 x,y,z 來定義一個 tuple 對象,對象元素有3個,然後通過坐标值來引用相應的值即可。

from collections import namedtuple
from collections import deque
from collections import defaultdict
from collections import OrderedDict
from collections import Counter


def testNamedTuple():
    vector=namedtuple('vector',['x','y','z'])
    flag=vector(3,4,5)
    print(type(flag))
    print(isinstance(flag,vector))
    print(isinstance(flag,tuple)) #通過這裡的判定我們就可以知曉它是元組類型
    print(flag.x,flag.y,flag.z)
           

複制

(2). testDeque函數

deque是棧和隊列的一種廣義實作,deque是 "double-end queue" 的簡稱;

deque支援線程安全、有效記憶體地以近似O(1)的性能在 deque 的兩端插入和删除元素,盡管 list 也支援相似的操作,但是它主要在固定長度操作上的優化,進而在 pop(0) 和 insert(0,v)(會改變資料的位置和大小)上有O(n)的時間複雜度。

在資料結構中,我們知道隊列和堆棧是兩個非常重要的資料類型,一個先進先出,一個後進先出。

在 python 中,使用 list 存儲資料時,按索引通路元素很快,但是插入和删除元素就很慢,因為 list 是線性存儲,資料量大的時候,插入和删除效率很低。

deque是為了高效實作插入和删除操作的雙向連結清單結構,非常适合實作隊列和堆棧這樣的資料結構。

def testDeque():
    list1=[x*x for x in range(101)]
    delist=deque(list1) #對清單進行了一次再處理,讓list1清單變成了雙向連結清單結構
    delist.append(1000)#将x添加到deque的右側
    delist.appendleft(2000)#将x添加到deque的左側
    delist.pop(1000)#移除和傳回deque中最右側的元素,如果沒有元素,将會報出IndexError;
    delist.popleft()#移除和傳回deque中最左側的元素,如果沒有元素,将會報出IndexError;
    delist.count(1)#傳回deque中元素等于1的個數
    delist.remove(10000)#移除第一次出現的value,如果沒有找到,報出ValueError;
    delist.reverse()#反轉deque中的元素,并傳回None;
    list2=[1,3,4,5]
    delist.extend(list2)#将可疊代變量iterable中的元素添加至deque的右側
    delist.extendleft(list2)#将變量iterable中的元素添加至deque的左側,往左側添加序列的順序與可疊代變量iterable中的元素相反
    delist.maxlen()#隻讀的屬性,deque的最大長度,如果無解,就傳回None
    delist.rotate(1)#從右側反轉n步,如果n為負數,則從左側反轉
    delist.clear()#将deque中的元素全部删除,最後長度為0;
           

複制

(3). testDefaultdict函數

defaultdict是内置資料類型 dict 的一個子類,基本功能與 dict 一樣,隻是重寫了一個方法__missing__(key)和增加了一個可寫的對象變量 default_factory。

使用 dict 字典類型時,如果引用的 key 不存在,就會抛出 KeyError。如果希望 Key 不存在時,傳回一個預設值,就可以用 defaultdict。

def testDefaultdict():
    dict1= defaultdict(lambda: 'default') #Key不存在時,傳回一個預設值,就可以用default,defaultdict的其他行為跟dict是完全一樣的
    dict1["k1"]="v1"
    print(dict1["k2"])

    list2= [('yellow',11),('blue',2),('yellow',3),('blue',4),('red',5),('red',10)]
    dict1 = defaultdict(list)#使用list作為default_factory,很容易将一個key-value的序列轉換為一個關于list的詞典
    for k,v in list2:
        dict1[k].append(v)
    print(dict1)
           

複制

(4). testOrderedDict函數

OrderedDict類似于正常的詞典,隻是它記住了元素插入的順序,當在有序的詞典上疊代時,傳回的元素就是它們第一次添加的順序。這樣 dict 就是一個有序的字典。

使用 dict 時,key 是無序的。在對 dict 做疊代時,我們無法确定 key 的順序。但是如果想要保持 key 的順序,可以用 OrderedDict。

def testOrderedDict():
    dict1=dict([('aaa', 111), ('ddd',444),('bbb', 222), ('ccc', 333)])
    print(dict1)

    dict2 = OrderedDict([('ddd',444),('aaa', 111), ('bbb', 222), ('ccc', 333)])#OrderedDict的key會按照插入的順序排列,不是key本身排序
    print(dict2)

    dict3 = {"banana": 33, "apple": 222, "pear": 1, "orange": 4444}
    # dict sorted by key
    dict4=OrderedDict(sorted(dict3.items(), key=lambda t: t[0]))
    print("dict4",dict4)
    # dict sorted by value
    dict5=OrderedDict(sorted(dict3.items(), key=lambda t: t[1]))
    print("dict5",dict5)
    # dict sorted by length of key string
    dict6 = OrderedDict(sorted(dict3.items(), key=lambda t: len(t[0])))
    print("dict6",dict6)
    print(dict6['apple'])
           

複制

(5). testCounter函數
def testCounter():
    '''counter可以支援友善、快速的計數'''
    str1="abcdefgabcedergeghdjlkabcdefe" #将可疊代的字元串初始化counter
    str2=Counter(str1)
    print(str2) #從輸出的内容來看,Counter實際上也是dict的一個子類
    for k,v in str2.items():
        print(k,v)

    dict3 = {"banana": 33, "apple": 222, "pear": 1, "orange": 4444,"apples":2}#将dict初始化counter
    dict4=Counter(dict3)
    print(dict4)
    print(dict4["test"])#Counter對象類似于字典,如果某個項缺失,會傳回0,而不是報出KeyError;

    dict5=Counter(high=9,age=33,money=-1)#将args初始化counter
    print(dict5)
    #elements傳回一個疊代器,每個元素重複的次數為它的數目,順序是任意的順序,如果一個元素的數目少于1,那麼elements()就會忽略它;
    list1=list(dict5.elements())
    print(list1)

    #most_common傳回一個清單,包含counter中n個最大數目的元素
    #,如果忽略n或者為None,most_common()将會傳回counter中的所有元素,元素有着相同數目的将會以任意順序排列;
    str1 = "abcdefgabcedergeghdjlkabcdefe"
    list1=Counter(str1).most_common(3)
    print(list1)

if __name__ == '__main__':
    # testNamedTuple()
    # testCounter()
    testDefaultdict()
    # testDeque()
    # testOrderedDict()           

複制