โมดูล collections ให้ Container Datatypes ที่ทรงพลังกว่า Built-ins (dict, list, set, tuple)
Container Types ภาพรวม
| Class | คำอธิบาย | ใช้เมื่อไหร่ |
|---|---|---|
namedtuple | Tuple ที่มีชื่อ Field | Immutable Record, Lightweight Object |
deque | Double-Ended Queue O(1) | Queue, Stack, Sliding Window, BFS |
Counter | Dict Subclass นับ Hashable Objects | Frequency Counting, Multiset |
OrderedDict | Dict จดจำ Insertion Order | LRU Cache, Ordered Config |
ChainMap | รวมหลาย Dict เป็น View เดียว | Config Layers, Scope Chain |
defaultdict | Dict ที่มี Default Factory | Grouping, Counting, Nested Dict |
UserDict/UserList/UserString | Wrapper สำหรับ Subclassing | Custom Dict/List Behavior |
Deque (Double-Ended Queue)
from collections import deque
dq = deque('124dfre')
dq.append('x') # Right
dq.appendleft('B') # Left
dq.pop() # Right
dq.popleft() # Left
dq.rotate(3) # Rotate Right 3
dq.reverse() # Reverse In-place
Methods: append, appendleft, pop, popleft, extend, extendleft, rotate, reverse, index, count, insert, remove, clear
Counter
from collections import Counter
cnt = Counter(['ABC', 'PQR', 'ABC', 'ABC', 'PQR', 'Mno', 'xyz', 'PQR', 'ABC', 'xyz'])
print(cnt) # Counter({'ABC': 4, 'PQR': 3, 'xyz': 2, 'Mno': 1})
print(cnt.most_common(2)) # [('ABC', 4), ('PQR', 3)]
print(list(cnt.elements())) # ['ABC', 'ABC', 'ABC', 'ABC', 'PQR', ...]
# Arithmetic
c1 = Counter(a=3, b=1)
c2 = Counter(a=1, b=2)
print(c1 + c2) # Counter({'a': 4, 'b': 3})
print(c1 - c2) # Counter({'a': 2}) (เฉพาะ Positive)
print(c1 & c2) # Intersection (Min)
print(c1 | c2) # Union (Max)
ChainMap
from collections import ChainMap
defaults = {'host': 'localhost', 'port': 8080}
user_config = {'port': 3000}
env_config = {'host': '0.0.0.0'}
config = ChainMap(env_config, user_config, defaults)
print(config['host']) # '0.0.0.0'
print(config['port']) # 3000
config = config.new_child({'debug': True}) # Add Layer
OrderedDict
from collections import OrderedDict
od = OrderedDict()
od['a'] = 1
od['b'] = 2
od.move_to_end('a') # Move to End
od.move_to_end('b', last=False) # Move to Front
od.popitem(last=False) # Pop Front (FIFO)
defaultdict
from collections import defaultdict
# Grouping
words = ['apple', 'bat', 'bar', 'atom', 'book']
groups = defaultdict(list)
for w in words:
groups[w[0]].append(w)
# {'a': ['apple', 'atom'], 'b': ['bat', 'bar', 'book']}
# Nested Defaultdict
tree = lambda: defaultdict(tree)
data = tree()
data['a']['b']['c'] = 1
UserDict / UserList / UserString
from collections import UserDict
class ValidatedDict(UserDict):
def __setitem__(self, key, value):
if not isinstance(key, str):
raise TypeError("Keys must be strings")
super().__setitem__(key, value)
vd = ValidatedDict()
vd['name'] = 'John' # OK
# vd[123] = 'Error' # TypeError
สรุปเลือกใช้
- ต้องการ Queue/Stack -> deque
- นับ Frequency -> Counter
- Config Layers -> ChainMap
- Dict ที่ต้องการ Order -> OrderedDict (หรือ dict ใน 3.7+)
- Dict ที่ Auto-create Default -> defaultdict
- Custom Container Behavior -> UserDict/UserList