Python模塊: collections

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

計數器的更新(updatesubtract

可以使用一個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_factoryset使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]))]
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章