Python作爲一個“內置電池”的編程語言,標準庫裏面擁有非常多好用的模塊。比如今天想給大家 介紹的 collections
就是一個非常好的例子。
基本介紹
我們都知道,Python擁有一些內置的數據類型,比如str
, int
, list
, tuple
, dict
等, collections模塊在這些內置數據類型的基礎上,提供了幾個額外的數據類型:
namedtuple()
: 生成可以使用名字來訪問元素內容的tuple子類deque
: 雙端隊列,可以快速的從另外一側追加和推出對象Counter
: 計數器,主要用來計數OrderedDict
: 有序字典defaultdict
: 帶有默認值的字典
1,namedtuple()
Python中存儲系列數據,比較常見的數據類型有list,除此之外,還有tuple數據類型。相比與list,tuple中的元素不可修改,在映射中可以當鍵使用。tuple元組的item只能通過index訪問,collections模塊
的namedtuple
子類不僅可以使用item的index訪問item,還可以通過item的name進行訪問。可以將namedtuple理解爲c中的struct結構,其首先將各個item命名,然後對每個item賦予數據。
coordinate = namedtuple('Coordinate', ['x', 'y'])
co = coordinate(10,20)
print (co.x,co.y)
print (co[0],co[1])
co = coordinate._make([100,200])
print (co.x,co.y)
co = co._replace(x = 30)
print (co.x,co.y)
10 20
10 20
100 200
30 200
from collections import namedtuple
websites = [
('Sohu', 'http://www.google.com/', u'張朝陽'),
('Sina', 'http://www.sina.com.cn/', u'王志東'),
('163', 'http://www.163.com/', u'丁磊')
]
Website = namedtuple('Websites', ['name', 'url', 'founder'])
# Website 對象名
# 參數'Websites': Websites(name='Sohu', url='http://www.google.com/', founder='張朝陽')
# 指打印顯示的名字
for website in websites:
website = Website._make(website)
print(website)
'''
Websites(name='Sohu', url='http://www.google.com/', founder='張朝陽')
Websites(name='Sina', url='http://www.sina.com.cn/', founder='王志東')
Websites(name='163', url='http://www.163.com/', founder='丁磊')
'''
print(website.name, website.url, website.founder)
'''
Sohu http://www.google.com/ 張朝陽
Sina http://www.sina.com.cn/ 王志東
163 http://www.163.com/ 丁磊
'''
2,deque ()
參考:https://blog.csdn.net/u010339879/article/details/80767293
deque 是一個雙端隊列, 如果要經常從兩端append 的數據, 選擇這個數據結構就比較好了, 如果要實現隨機訪問,不建議用這個,請用列表.
deque 優勢就是可以從兩邊append ,appendleft 數據. 這一點list 是沒有的.
指定隊列長度
from collections import deque
# 可以指定 隊列的長度
mydeque = deque(maxlen=10)
print(mydeque.maxlen) # 10
從兩端添加元素
# 默認從右邊加入
mydeque.append(10)
mydeque.append(12)
print(mydeque) # deque([10, 12], maxlen=10)
# 也可以從左邊加入
mydeque.appendleft('a')
mydeque.appendleft('b')
mydeque.appendleft('c')
print(mydeque) # deque(['c', 'b', 'a', 10, 12], maxlen=10)
取隊列元素
# 出隊列,返回出隊列的元素
# 可以從左邊也可以從右邊 出隊列
mydeque.pop()
mydeque.popleft()
查看隊列元素個數
# 查看 隊列裏面元素個數
print(len(mydeque))
統計元素的個數
# 統計元素的個數
#統計a 有幾個
print(mydeque.count('a'))
在某個位置insert
一個元素
# insert(i, x)
# Insert x into the deque at position i.
d1
Out[31]: deque([10, 12, 13, 14])
d1.insert(2,'frank')
d1
Out[33]: deque([10, 12, 'frank', 13, 14])
翻轉操作
#翻轉操作
# deque.reverse()
mydeque
Out[52]: deque([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
mydeque.reverse()
mydeque
Out[54]: deque([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])
remove
移除某個元素
mydeque
Out[23]: deque(['e', 'd', 'c', 'b', 'a', 10, 12])
mydeque.remove(10)
mydeque
Out[25]: deque(['e', 'd', 'c', 'b', 'a', 12])
清空隊列元素 clear
mydeque
Out[46]: deque([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
mydeque.clear
Out[47]: <function deque.clear>
mydeque.clear()
mydeque
Out[49]: deque([])
重要方法說明
-
rotate
方法
移動到最後一個,佔用第一個位置,循環移動, value 是步長
rotate(value) 對隊列實行旋轉操作(每個元素依次向後移動value步,最後一個移動到第一個算一步)from collections import deque d = deque() d.extend(['a', 'b', 'c', 'd', 'e']) d.rotate(2) # 指定次數,默認1次 print(d) # deque(['d', 'e', 'a', 'b', 'c'])
-
maxlen
要說明一下, 如果指定了maxlen
如果構建deque 的時候,指定了maxlen, 則可以通過 d.maxlen 來獲得dueue的最大長度.
如果插入的數據大於 maxlen 則會自動刪除舊的元素.刪除 什麼元素,取決於, 從哪邊添加數據.來看一下例子.d = deque(list(range(5)),maxlen=5) d Out[21]: deque([0, 1, 2, 3, 4]) d.maxlen Out[26]: 5 # 從左邊添加元素, # 元素4 被擠出 隊列 d.appendleft('frank') d Out[23]: deque(['frank', 0, 1, 2, 3]) # 從右邊添加元素, 元素 'frank' 被擠出隊列. d Out[23]: deque(['frank', 0, 1, 2, 3]) d.append('xiaoming') d Out[25]: deque([0, 1, 2, 3, 'xiaoming'])
3,Counter()
參考:http://www.pythoner.com/205.html
Counter類的目的是用來跟蹤值出現的次數。它是一個無序的容器類型,以字典的鍵值對形式存儲,其中元素作爲key
,其計數作爲value
。計數值可以是任意的Interger(包括0和負數)
創建
下面的代碼說明了Counter類創建的四種方法:
>>> c = Counter() # 創建一個空的Counter類
>>> c = Counter('gallahad') # 從一個可iterable對象(list、tuple、dict、字符串等)創建
>>> c = Counter({'a': 4, 'b': 2}) # 從一個字典對象創建
>>> c = Counter(a=4, b=2) # 從一組鍵值對創建
計數值的訪問與缺失的鍵
當所訪問的鍵不存在時,返回0,而不是KeyError;否則返回它的計數。
>>> c = Counter("abcdefgab")
>>> c["a"]
2
>>> c["c"]
1
>>> c["h"]
0
計數器的更新(update
和subtract
)
可以使用一個iterable對象或者另一個Counter對象來更新鍵值。
計數器的更新包括增加和減少兩種。其中,增加使用update()方法
:
>>> c = Counter('which')
>>> c.update('witch') # 使用另一個iterable對象更新
>>> c['h']
3
>>> d = Counter('watch')
>>> c.update(d) # 使用另一個Counter對象更新
>>> c['h']
4
減少則使用subtract()方法
:
>>> c = Counter('which')
>>> c.subtract('witch') # 使用另一個iterable對象更新
>>> c['h']
1
>>> d = Counter('watch')
>>> c.subtract(d) # 使用另一個Counter對象更新
>>> c['a']
-1
鍵的刪除
當計數值爲0時,並不意味着元素被刪除,刪除元素應當使用del
>>> c = Counter("abcdcba")
>>> c
Counter({'a': 2, 'c': 2, 'b': 2, 'd': 1})
>>> c["b"] = 0
>>> c
Counter({'a': 2, 'c': 2, 'd': 1, 'b': 0})
>>> del c["a"]
>>> c
Counter({'c': 2, 'b': 2, 'd': 1})
elements()
返回一個迭代器。元素被重複了多少次,在該迭代器中就包含多少個該元素。元素排列無確定順序,個數小於1的元素不被包含。
>>> c = Counter(a=4, b=2, c=0, d=-2)
>>> list(c.elements())
['a', 'a', 'a', 'a', 'b', 'b']
most_common([n])
most_common(n)
按照counter的計數,按照降序,返回前n項組成的list; n忽略時返回全部
返回一個TopN列表。如果n沒有被指定,則返回所有元素。當多個元素計數值相同時,排列是無確定順序的。
>>> c = Counter('abracadabra')
>>> c.most_common()
[('a', 5), ('r', 2), ('b', 2), ('c', 1), ('d', 1)]
>>> c.most_common(3)
[('a', 5), ('r', 2), ('b', 2)]
算術和集合操作
+
、-
、&
、|
操作也可以用於Counter。其中&和|操作分別返回兩個Counter對象各元素的最小值和最大值。需要注意的是,得到的Counter對象將刪除小於1的元素。
>>> c = Counter(a=3, b=1)
>>> d = Counter(a=1, b=2)
>>> c + d # c[x] + d[x]
Counter({'a': 4, 'b': 3})
>>> c - d # subtract(只保留正數計數的元素)
Counter({'a': 2})
>>> c & d # 交集: min(c[x], d[x])
Counter({'a': 1, 'b': 1})
>>> c | d # 並集: max(c[x], d[x])
Counter({'a': 3, 'b': 2})
常見做法:
sum(c.values()) # 繼承自字典的.values()方法返回values的列表,再求和
c.clear() # 繼承自字典的.clear()方法,清空counter
list(c) # 返回key組成的list
set(c) # 返回key組成的set
dict(c) # 轉化成字典
c.items() # 轉化成(元素,計數值)組成的列表
Counter(dict(list_of_pairs)) # 從(元素,計數值)組成的列表轉化成Counter
c.most_common()[:-n-1:-1] # 最小n個計數的(元素,計數值)組成的列表
c += Counter() # 利用counter的相加來去除負值和0的值
4,OrderedDict()
Python中的字典對象可以以“鍵:值”的方式存取數據。OrderedDict是它的一個子類,實現了對字典對象中元素的排序。
import collections
print('Regular dictionary:')
d={}
d['a']='A'
d['b']='B'
d['c']='C'
for k,v in d.items():
print( k,v)
print( '\nOrderedDict:')
d=collections.OrderedDict()
d['a']='A'
d['b']='B'
d['c']='C'
for k,v in d.items():
print( k,v)
Regular dictionary:
a A
c C
b B
OrderedDict:
a A
b B
c C
可以看到,同樣是保存了ABC三個元素,但是使用OrderedDict會根據放入元素的先後順序進行排序。由於進行了排序,所以OrderedDict對象的字典對象,如果其順序不同那麼Python也會把他們當做是兩個不同的對象,比如下面的代碼:
import collections
print('Regular dictionary:')
d1={}
d1['a']='A'
d1['b']='B'
d1['c']='C'
d2={}
d2['c']='C'
d2['a']='A'
d2['b']='B'
print(d1==d2)
print('\nOrderedDict:')
d1=collections.OrderedDict()
d1['a']='A'
d1['b']='B'
d1['c']='C'
d2=collections.OrderedDict()
d2['c']='C'
d2['a']='A'
d2['b']='B'
print(d1==d2)
Regular dictionary:
True
OrderedDict:
False
fromkeys
(指定一個列表,把列表中的值作爲字典的key,生成一個字典)
import collections
dic = collections.OrderedDict()
name = ['tom','lucy','sam']
print(dic.fromkeys(name))
print(dic.fromkeys(name,20))
#輸出:OrderedDict([('tom', None), ('lucy', None), ('sam', None)])
# OrderedDict([('tom', 20), ('lucy', 20), ('sam', 20)])
items()
(返回由“鍵值對組成元素“的列表)
import collections
dic = collections.OrderedDict()
dic['k1'] = 'v1'
dic['k2'] = 'v2'
print(dic.items())
#輸出:odict_items([('k1', 'v1'), ('k2', 'v2')])
keys()
(獲取字典所有的key,返回一個列表)
import collections
dic = collections.OrderedDict()
dic['k1'] = 'v1'
dic['k2'] = 'v2'
print(dic.keys())
# 輸出:odict_keys(['k1', 'k2'])
values()
(獲取字典所有的value,返回一個列表)
import collections
dic = collections.OrderedDict()
dic['k1'] = 'v1'
dic['k2'] = 'v2'
dic['k3'] = 'v3'
print(dic.values())
# 輸出:odict_values(['v1', 'v2', 'v3'])
5,defaultdict()
class collections.default([default_factory[, ...]])
返回一個類字典對象。defaultdict是內置類型dict的子類。他重寫了父的一個方法並且增加了一個可以的實例變量。餘下的功能與字典的一樣,在這裏就不寫文檔了。
第一個參數爲default_factory
屬性提供初始值;default_factory
的默認值爲None.餘下的參數被視爲dict構造器的參數包括關鍵字參數
defaultdict 的例子
使用list
作爲default_factory
,他很容易的將一個以鍵值形式表現的序列分組成一個字典列表
>>> s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
>>> d = defaultdict(list)
>>> for k, v in s:
... d[k].append(v)
...
>>> d.items()
[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]
當每個key第一次被訪問時,他們肯定沒有在映射中:一個入口自動的被創建了使用default_factory函數返回一個空的列表。然後list.append()操作將值放入新的列表中。當key再次被訪問時,查找工作正常(返回這個key的列表)然後list.append()操作爲列表添加別外的值。這個技巧比等價的技藝(使用dict.setdefault())更簡節,更快
>>> d = {}
>>> for k, v in s:
... d.setdefault(k, []).append(v)
...
>>> d.items()
[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]
將default_factory
設置成int
使defaultdict對於計數非常有用
>>> s = 'mississippi'
>>> d = defaultdict(int)
>>> for k in s:
... d[k] += 1
...
>>> d.items()
[('i', 4), ('p', 2), ('s', 4), ('m', 1)]
當一個字每第一次被訪問時,這個字母在映射中不存在,因此default_factory函數調用int()
提供一個默認的0作爲count。然後自增操作計算每個字母出現的次數,
int()函數
總是返回0,因爲他是常量函數的一個特殊的例子。一個更快更靈活的方式是創建一個常量函數
設置default_factory
爲set
使defaultdict構建集合字典非常有用
>>> s = [('red', 1), ('blue', 2), ('red', 3), ('blue', 4), ('red', 1), ('blue', 4)]
>>> d = defaultdict(set)
>>> for k, v in s:
... d[k].add(v)
...
>>> d.items()
[('blue', set([2, 4])), ('red', set([1, 3]))]