python標准庫之collections介紹


collections----容器數據類型

collections模塊包含了除list、dict、和tuple之外的容器數據類型,如counter、defaultdict、deque、namedtuple、orderdict,下面將一一介紹。

Counter

初始化:

Counter 支持三種形式的初始化。它的構造函數可以調用序列,一個字典包含密鑰和計數,或使用關鍵字參數映射的字符串名稱。

import collections

print (collections.Counter(['a', 'b', 'c', 'a', 'b', 'b']))
print (collections.Counter({'a':2, 'b':3, 'c':1}))
print (collections.Counter(a=2, b=3, c=1))

輸出結果:

Counter({'b': 3, 'a': 2, 'c': 1})
Counter({'b': 3, 'a': 2, 'c': 1})
Counter({'b': 3, 'a': 2, 'c': 1})

空的Counter容器可以無參數構造,並采用update()方法進行更新

import collections

c = collections.Counter()
print ('Initial :', c)

c.update('abcdaab')
print ('Sequence:', c)

c.update({'a':1, 'd':5})
print ('Dict    :', c)

輸出結果:

Initial : Counter()
Sequence: Counter({'a': 3, 'b': 2, 'c': 1, 'd': 1})
Dict    : Counter({'d': 6, 'a': 4, 'b': 2, 'c': 1})

訪問計數:

當一個Counter被構造成功,它的值可以采用字典進行訪問

import collections

c = collections.Counter('abcdaab')

for letter in 'abcde':
    print ('%s : %d' % (letter, c[letter]))

結果:

a : 3
b : 2
c : 1
d : 1
e : 0

elements()方法可以返回一個包含所有Counter數據的迭代器

import collections

c = collections.Counter('extremely')
c['z'] = 0
print(c)
print (list(c.elements()))
Counter({'e': 3, 'm': 1, 'l': 1, 'r': 1, 't': 1, 'y': 1, 'x': 1, 'z': 0})
['e', 'e', 'e', 'm', 'l', 'r', 't', 'y', 'x']

most_common()返回前n個最多的數據

import collections

c=collections.Counter('aassdddffff')
for letter, count in c.most_common(2):
    print ('%s: %d' % (letter, count))
f: 4
d: 3

算法:

Counter實例支持聚合結果的算術和集合操作。

import collections

c1 = collections.Counter(['a', 'b', 'c', 'a', 'b', 'b'])
c2 = collections.Counter('alphabet')

print ('C1:', c1)
print ('C2:', c2)

print ('\nCombined counts:')
print (c1 + c2)

print ('\nSubtraction:')
print (c1 - c2)

print ('\nIntersection (taking positive minimums):')
print (c1 & c2)

print ('\nUnion (taking maximums):')
print (c1 | c2)
C1: Counter({'b': 3, 'a': 2, 'c': 1})
C2: Counter({'a': 2, 'l': 1, 'p': 1, 'h': 1, 'b': 1, 'e': 1, 't': 1})

Combined counts:
Counter({'a': 4, 'b': 4, 'c': 1, 'l': 1, 'p': 1, 'h': 1, 'e': 1, 't': 1})

Subtraction:
Counter({'b': 2, 'c': 1})

Intersection (taking positive minimums):
Counter({'a': 2, 'b': 1})

Union (taking maximums):
Counter({'b': 3, 'a': 2, 'c': 1, 'l': 1, 'p': 1, 'h': 1, 'e': 1, 't': 1})

 



 

defaultdict

標准字典包括setdefault方法()獲取一個值,如果值不存在,建立一個默認。相比之下,defaultdict允許調用者在初始化時預先設置默認值。

import collections

def default_factory():
    return 'default value'

d = collections.defaultdict(default_factory, foo='bar')
print ('d:', d)
print ('foo =>', d['foo'])
print ('x =>', d['x'])
d: defaultdict(<function default_factory at 0x000002567E713E18>, {'foo': 'bar'})
foo => bar
x => default value

 



Deque

雙端隊列,支持從兩端添加和刪除元素。更常用的棧和隊列是退化形式的雙端隊列,僅限於一端在輸入和輸出。

import collections

d = collections.deque('abcdefg')
print ('Deque:', d)
print ('Length:', len(d))
print ('Left end:', d[0])
print ('Right end:', d[-1])

d.remove('c')
print ('remove(c):', d)
Deque: deque(['a', 'b', 'c', 'd', 'e', 'f', 'g'])
Length: 7
Left end: a
Right end: g
remove(c): deque(['a', 'b', 'd', 'e', 'f', 'g'])

雙端隊列從左右兩端插入數據

import collections

# 右端插入
d = collections.deque()
d.extend('abcdefg')
print ('extend    :', d)
d.append('h')
print ('append    :', d)

# 左端插入
d = collections.deque()
d.extendleft('abcdefg')
print ('extendleft:', d)
d.appendleft('h')
print ('appendleft:', d)
extend    : deque(['a', 'b', 'c', 'd', 'e', 'f', 'g'])
append    : deque(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'])
extendleft: deque(['g', 'f', 'e', 'd', 'c', 'b', 'a'])
appendleft: deque(['h', 'g', 'f', 'e', 'd', 'c', 'b', 'a'])

類似地,雙端隊列的元素可以從兩端獲取。

import collections

print ('From the right:')
d = collections.deque('abcdefg')
while True:
    try:
        print (d.pop())
    except IndexError:
        break

print ('\nFrom the left:')
d = collections.deque('abcdefg')
while True:
    try:
        print (d.popleft())
    except IndexError:
        break
From the right:
g
f
e
d
c
b
a

From the left:
a
b
c
d
e
f
g

由於雙端隊列是線程安全的,在單獨的線程中內容甚至可以從兩端同時消費。

import collections
import threading
import time

candle = collections.deque(xrange(11))

def burn(direction, nextSource):
    while True:
        try:
            next = nextSource()
        except IndexError:
            break
        else:
            print ('%8s: %s' % (direction, next))
            time.sleep(0.1)
    print ('%8s done' % direction)
    return

left = threading.Thread(target=burn, args=('Left', candle.popleft))
right = threading.Thread(target=burn, args=('Right', candle.pop))

left.start()
right.start()

left.join()
right.join()
    Left: 0
   Right: 10
   Right: 9
     Left: 1
   Right: 8
    Left: 2
   Right: 7
    Left: 3
   Right: 6
    Left: 4
   Right: 5
    Left done
   Right done

隊列的另一個有用的功能是在任意方向旋轉,通俗來講就是隊列的左移右移

import collections

d = collections.deque(xrange(10))
print ('Normal        :', d)

d = collections.deque(xrange(10))
d.rotate(2)
print ('Right rotation:', d)

d = collections.deque(xrange(10))
d.rotate(-2)
print ('Left rotation :', d)
Normal        : deque([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
Right rotation: deque([8, 9, 0, 1, 2, 3, 4, 5, 6, 7])
Left rotation : deque([2, 3, 4, 5, 6, 7, 8, 9, 0, 1])


namedtuple

標准的元組使用數值索引來訪問其成員

bob = ('Bob', 30, 'male')
print ('Representation:', bob)

jane = ('Jane', 29, 'female')
print ('\nField by index:', jane[0])

print ('\nFields by index:')
for p in [ bob, jane ]:
    print ('%s is a %d year old %s' % p)
Representation: ('Bob', 30, 'male')

Field by index: Jane

Fields by index:
Bob is a 30 year old male
Jane is a 29 year old femal

記住每個索引對應的值是很容易出錯的,尤其是在元組有多個元素的情況下。namedtuple為每個成員分配了名字。

import collections

Person = collections.namedtuple('Person', 'name age gender')

print ('Type of Person:', type(Person))

bob = Person(name='Bob', age=30, gender='male')
print ('\nRepresentation:', bob)

jane = Person(name='Jane', age=29, gender='female')
print ('\nField by name:', jane.name)

print ('\nFields by index:')
for p in [ bob, jane ]:
    print ('%s is a %d year old %s' % p)
Type of Person: <type 'type'>

Representation: Person(name='Bob', age=30, gender='male')

Field by name: Jane

Fields by index:
Bob is a 30 year old male
Jane is a 29 year old female

字段名稱解析,無效值會導致ValueError

import collections

try:
    collections.namedtuple('Person', 'name class age gender')
except ValueError, err:
    print (err)

try:
    collections.namedtuple('Person', 'name age gender age')
except ValueError, err:
    print (err)
Type names and field names cannot be a keyword: 'class'
Encountered duplicate field name: 'age'


OrderedDict

OrderedDict是字典子類,記得其內容被添加的順序

import collections

print ('Regular dictionary:')
d = {}
d['a'] = 'A'
d['b'] = 'B'
d['c'] = 'C'
d['d'] = 'D'
d['e'] = 'E'

for k, v in d.items():
    print( k, v)

print ('\nOrderedDict:')
d = collections.OrderedDict()
d['a'] = 'A'
d['b'] = 'B'
d['c'] = 'C'
d['d'] = 'D'
d['e'] = 'E'

for k, v in d.items():
    print (k, v)
Regular dictionary:
a A
c C
b B
e E
d D

OrderedDict:
a A
b B
c C
d D
e E

 

參考來源:https://pymotw.com/2/collections/index.html#module-collections

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM