1. 程式人生 > >【人人都是Pythoner】【超全】python的collections模組詳解

【人人都是Pythoner】【超全】python的collections模組詳解

前言:

python中內建容器包括list、dict、set、tuple,而python中的collections模組則另引入了五種資料結構,更好地滿足編碼需求。

下文驗證資料型別方法用到的程式碼放在了我的github上,歡迎下載:
AdvancingMsCat的github


collections 是python內部的集合模組,內建以下幾種資料型別:

1、namedtuple(‘name’, [list]):
tuple是不可變的元組,如定義座標點(1,2)、(3,4),但很難直接從程式碼看出這是表示座標的,為了增加程式碼的可讀性,我們可以用 ** namedtuple() ** 建立自定義的tuple物件,這個物件是tuple 的子類。

如用(x,y)表示一個點:

from  collections import namedtuple #從collections匯入資料型別
Point = namedtuple('Point',['x','y'])#自定義tuple型別Point
p = Point(1,3)
print(isinstance(p,Point))#p是Point型別的例項
print(p)#Point(x=1, y=3)
print (p.x)#1
print (p.y)#3
#也可以定義其他型別
Circle = namedtuple('Circle',['x','y','r']) #自定義tuple型別Circle

這樣的一個tuple物件有了可被引用的名稱 Point,並且可以通過引用物件屬性來訪問元組元素 。

2、Counter()
Counter是一個計數器,用來跟蹤值出現的次數。它是一個無序的容器型別,以字典的鍵值對形式儲存,其中元素作為key,其計數作為value。

#統計字串中各個字元出現的個數
from collections import Counter
#從可iterable資料型別(list,tuple,dict)建立Counter型別例項

#從字串建立
s = ' programming '
c = Counter(s);
print(c)#Counter({' ': 2, 'r': 2, 'g': 2, 'm': 2, 'p': 1, 'o': 1, 'a': 1, 'i': 1, 'n': 1})
#預設按鍵值對從大到小輸出
#從字典型別建立
cdict = Counter({'a':4,'b':5})
print (cdict)#output:Counter({'b': 5, 'a': 4})

#從鍵值對建立,a b指的是鍵值,不能加引號
ckeys = Counter(a=5,b=6)
print(ckeys)#output:Counter({'b': 6, 'a': 5})
print(type(c))#<class 'collections.Counter'>


#返回計數器TopN部分
print(c.most_common())#[(' ', 2), ('r', 2), ('g', 2), ('m', 2), ('p', 1), ('o', 1), ('a', 1), ('i', 1), ('n', 1)]
print(c.most_common(5))#返回出現頻率最高的五個元素[(' ', 2), ('r', 2), ('g', 2), ('m', 2), ('p', 1)]
#注意到c.most_common()返回型別為list
print(type(c.most_common()))#<class 'list'>
#那麼就可以取出現次數最少的幾個元素
print(c.most_common()[:-4:-1])#出現次數最少的3個元素[('n', 1), ('i', 1), ('a', 1)]
print(c['m'])#2返回元素出現次數


#計數器內容增加 update
c.update('mmm')#引數為字串型別
print(c['m'])#5
print(c['a'])#1
c2=Counter('aaa')
c.update(c2)#引數為Counter型別
print(c['m'])#5
print(c['a'])#4,增加了了三個'a'
print('=======')

#計數器內容減少 subtract
print(c['b'])#訪問的鍵不存在時,輸出0,而不會報錯.output:0
c.subtract('aab')
print(c['a'])#,減少了兩個'a'  output:2
print(c['b'])#output:-1

#del 刪除鍵值
print(c)#output:Counter({'m': 5, ' ': 2, 'r': 2, 'g': 2, 'a': 2, 'p': 1, 'o': 1, 'i': 1, 'n': 1, 'b': -1})
del c['a']
print(c)#output:Counter({'m': 5, ' ': 2, 'r': 2, 'g': 2, 'p': 1, 'o': 1, 'i': 1, 'n': 1, 'b': -1}) 沒有'a'
print(c['a'])#0


#element() 返回迭代器
print(list(c.elements()))#[' ', ' ', 'p', 'r', 'r', 'o', 'g', 'g', 'm', 'm', 'm', 'm', 'm', 'i', 'n'],排列無序,不包括個數小於1的鍵值

#c中的鍵值轉換為list、set、dict型別
print(list(c))#[' ', 'p', 'r', 'o', 'g', 'm', 'i', 'n', 'b']
print(set(c))#{'g', 'b', 'o', 'r', ' ', 'm', 'p', 'i', 'n'}
print(dict(c))#{' ': 2, 'p': 1, 'r': 2, 'o': 1, 'g': 2, 'm': 5, 'i': 1, 'n': 1, 'b': -1}

#淺拷貝
d = c.copy()
print(c==d)#True

#加減算術操作,沒有乘除
a = Counter(a = 4,b = 5)
b = Counter(c= 7,b =3)
print(a+b)#Counter({'b': 8, 'c': 7, 'a': 4})
print(a-b)#Counter({'a': 4, 'b': 2})subtract 只保留正數計數的元素


print(a&b)#Counter({'b': 3}) 輸出元素交集 min(a,b)
print(a|b)#Counter({'c': 7, 'b': 5, 'a': 4}) 輸出元素並集 max(a,b)

#求鍵值技術的和
print(sum(a.values()))#9

#重置counter物件
a.clear()
print(a)#Counter(),沒有刪除
print(b.items())#dict_items([('c', 7), ('b', 3)])

Counter 在演算法題中的應用:
【死磕演算法之1刷leetcode】954. Array of Doubled Pairs

3、deque()
在python 中list查詢時間複雜度為O(1),但是插入和刪除元素時間複雜度為O(n),即耗時會隨著資料規模線性增長。
deque增刪元素的時間複雜度為O(1)

from collections import deque
q = deque([1,3,4])
q.pop()
print(q)#deque([1, 3])
q.append(9)
print(q)#deque([1, 3, 9])
q.appendleft(4)#從頭部新增元素
print(q)#deque([4, 1, 3, 9])
q.popleft()#刪除頭部元素
print(q)#deque([1, 3, 9])

4、OrderedDict()
有序字典,認為字典是有序的,按照建立orderdict例項輸入的鍵值對順序排列,而不是按照key值本身的順序。

# 普通Dict型別認為字典是無序的,OrderedDict認為字典是有序的,因此對於鍵值對排列不同的兩個字典,OrderDict會認為是不同的
from collections import OrderedDict
print ('Regular dictionary:')
d2={}
d2['a']='A'
d2['b']='B'
d2['c']='C'

d3={}
d3['c']='C'
d3['a']='A'
d3['b']='B'

print (d2 == d3)#True

print ('\nOrderedDict:')
d4=OrderedDict()
d4['a']='A'
d4['b']='B'
d4['c']='C'

d5=OrderedDict()
d5['c']='C'
d5['a']='A'
d5['b']='B'

print  (d4==d5)#False

print ("Regular dictionary")
d={}
d['b']='B'
d['c']='C'
d['a']='A'
for k,v in d.items():
    print (k,v)#python3中字典dict正常按序輸出,從當前情況看,和orderdict沒有區別

print ("\nOrder dictionary")
d1 = OrderedDict()

d1['b'] = 'B'
d1['c'] = 'C'
d1['a'] = 'A'
d1['1'] = '1'
d1['2'] = '2'
for k,v in d1.items():
    print (k,v)
#b B
# c C
# a A
# 1 1
# 2 2

5、defaultDict:
當某鍵值不存在時返回預設值,傳統dict例項訪問不存在的鍵值,會返回keyError.

from collections import defaultdict
q =defaultdict(lambda:'445')#設定預設值
print(q['44'])#445

參考連結:廖雪峰python教程
不可不知的Python模組: collections
有空多看原始碼和官方教程pyhon·collections

因為本人最近也處於學習python階段,並會在CSDN上記錄總結知識點,如果上述有錯誤的地方還請大家批評指正!