Documentation Index Fetch the complete documentation index at: https://mintlify.com/python/cpython/llms.txt
Use this file to discover all available pages before exploring further.
The collections module provides specialized container datatypes that extend or provide alternatives to Python’s built-in containers (dict, list, set, tuple).
Module Import
from collections import Counter, defaultdict, deque, namedtuple, OrderedDict, ChainMap
Counter - Count Hashable Objects
Dictionary subclass for counting hashable objects.
Creating Counter
from collections import Counter
# From iterable
fruits = [ 'apple' , 'banana' , 'apple' , 'orange' , 'banana' , 'apple' ]
counter = Counter(fruits)
print (counter) # Counter({'apple': 3, 'banana': 2, 'orange': 1})
# From string
counter = Counter( 'abracadabra' )
print (counter) # Counter({'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1})
# From dictionary
counter = Counter({ 'red' : 4 , 'blue' : 2 })
# From keyword arguments
counter = Counter( cats = 4 , dogs = 8 )
Counter Operations
from collections import Counter
counter = Counter([ 'apple' , 'banana' , 'apple' , 'orange' , 'banana' , 'apple' ])
# Get count
print (counter[ 'apple' ]) # 3
print (counter[ 'grape' ]) # 0 (no KeyError)
# Most common
print (counter.most_common( 2 )) # [('apple', 3), ('banana', 2)]
# All elements
print ( list (counter.elements())) # ['apple', 'apple', 'apple', 'banana', 'banana', 'orange']
# Update counts
counter.update([ 'banana' , 'grape' ])
# Subtract counts
counter.subtract([ 'apple' , 'banana' ])
Counter Arithmetic
from collections import Counter
c1 = Counter([ 'a' , 'b' , 'c' , 'a' ])
c2 = Counter([ 'a' , 'b' , 'd' ])
# Addition
print (c1 + c2) # Counter({'a': 3, 'b': 2, 'c': 1, 'd': 1})
# Subtraction (keep only positive counts)
print (c1 - c2) # Counter({'a': 1, 'c': 1})
# Intersection (minimum)
print (c1 & c2) # Counter({'a': 1, 'b': 1})
# Union (maximum)
print (c1 | c2) # Counter({'a': 2, 'b': 1, 'c': 1, 'd': 1})
defaultdict - Dict with Default Values
Dictionary subclass that provides default values for missing keys.
Creating defaultdict
from collections import defaultdict
# With list as default
dd = defaultdict( list )
dd[ 'colors' ].append( 'red' )
dd[ 'colors' ].append( 'blue' )
print (dd) # defaultdict(<class 'list'>, {'colors': ['red', 'blue']})
# With int as default (useful for counting)
dd = defaultdict( int )
for word in [ 'apple' , 'banana' , 'apple' ]:
dd[word] += 1
print (dd) # defaultdict(<class 'int'>, {'apple': 2, 'banana': 1})
# With set as default
dd = defaultdict( set )
dd[ 'tags' ].add( 'python' )
dd[ 'tags' ].add( 'coding' )
# With custom default
def default_value ():
return 'N/A'
dd = defaultdict(default_value)
print (dd[ 'missing' ]) # 'N/A'
Practical Uses
from collections import defaultdict
# Group by key
data = [( 'fruit' , 'apple' ), ( 'veg' , 'carrot' ), ( 'fruit' , 'banana' )]
grouped = defaultdict( list )
for category, item in data:
grouped[category].append(item)
print ( dict (grouped)) # {'fruit': ['apple', 'banana'], 'veg': ['carrot']}
# Count by category
words = [ 'apple' , 'banana' , 'apple' , 'cherry' , 'banana' ]
count = defaultdict( int )
for word in words:
count[word] += 1
# Nested defaultdict
tree = lambda : defaultdict(tree)
users = tree()
users[ 'john' ][ 'age' ] = 30
users[ 'john' ][ 'city' ] = 'NYC'
deque - Double-Ended Queue
List-like container with fast appends and pops on both ends.
Creating deque
from collections import deque
# Empty deque
d = deque()
# From iterable
d = deque([ 1 , 2 , 3 , 4 , 5 ])
# With maximum length
d = deque([ 1 , 2 , 3 ], maxlen = 5 )
deque Operations
from collections import deque
d = deque([ 1 , 2 , 3 ])
# Append to right
d.append( 4 ) # deque([1, 2, 3, 4])
# Append to left
d.appendleft( 0 ) # deque([0, 1, 2, 3, 4])
# Pop from right
right = d.pop() # 4, deque([0, 1, 2, 3])
# Pop from left
left = d.popleft() # 0, deque([1, 2, 3])
# Extend
d.extend([ 4 , 5 ]) # deque([1, 2, 3, 4, 5])
d.extendleft([ 0 , - 1 ]) # deque([-1, 0, 1, 2, 3, 4, 5])
# Rotate
d.rotate( 2 ) # Rotate right
d.rotate( - 2 ) # Rotate left
deque Use Cases
from collections import deque
# Fixed-size rolling window
window = deque( maxlen = 3 )
for i in range ( 10 ):
window.append(i)
print ( list (window)) # Always max 3 items
# Queue (FIFO)
queue = deque()
queue.append( 'first' )
queue.append( 'second' )
item = queue.popleft() # 'first'
# Stack (LIFO)
stack = deque()
stack.append( 'first' )
stack.append( 'second' )
item = stack.pop() # 'second'
namedtuple - Tuple with Named Fields
Factory function for creating tuple subclasses with named fields.
Creating namedtuple
from collections import namedtuple
# Define a namedtuple class
Point = namedtuple( 'Point' , [ 'x' , 'y' ])
# Create instances
p1 = Point( 10 , 20 )
p2 = Point( x = 5 , y = 15 )
# Access fields
print (p1.x) # 10
print (p1.y) # 20
# Also works with indexing
print (p1[ 0 ]) # 10
# Unpack like regular tuple
x, y = p1
namedtuple Features
from collections import namedtuple
Person = namedtuple( 'Person' , [ 'name' , 'age' , 'city' ])
person = Person( 'Alice' , 30 , 'NYC' )
# Convert to dict
print (person._asdict()) # {'name': 'Alice', 'age': 30, 'city': 'NYC'}
# Replace fields (returns new instance)
updated = person._replace( age = 31 )
print (updated) # Person(name='Alice', age=31, city='NYC')
# Get field names
print (Person._fields) # ('name', 'age', 'city')
# Create from iterable
data = [ 'Bob' , 25 , 'LA' ]
person = Person._make(data)
# With defaults (Python 3.7+)
Person = namedtuple( 'Person' , [ 'name' , 'age' , 'city' ], defaults = [ 'Unknown' , 0 , 'Unknown' ])
OrderedDict - Dictionary That Remembers Order
As of Python 3.7+, regular dicts maintain insertion order. OrderedDict is mainly useful for its additional methods.
from collections import OrderedDict
# Create ordered dictionary
od = OrderedDict()
od[ 'first' ] = 1
od[ 'second' ] = 2
od[ 'third' ] = 3
# Move to end
od.move_to_end( 'first' ) # Moves 'first' to the end
od.move_to_end( 'third' , last = False ) # Moves 'third' to the beginning
# Pop items
od.popitem( last = True ) # Pop from end (LIFO)
od.popitem( last = False ) # Pop from beginning (FIFO)
ChainMap - Combine Multiple Dicts
Groups multiple dictionaries into a single view.
from collections import ChainMap
# Combine dictionaries
defaults = { 'color' : 'red' , 'user' : 'guest' }
config = { 'user' : 'admin' }
combined = ChainMap(config, defaults)
print (combined[ 'user' ]) # 'admin' (from config)
print (combined[ 'color' ]) # 'red' (from defaults)
# Update only affects first mapping
combined[ 'user' ] = 'root'
print (config) # {'user': 'root'}
print (defaults) # {'color': 'red', 'user': 'guest'}
# Add new mapping
new_config = { 'theme' : 'dark' }
combined = combined.new_child(new_config)
Practical Examples
Word Frequency Analysis
from collections import Counter
import re
def analyze_text ( text ):
"""Analyze word frequencies in text"""
words = re.findall( r ' \w + ' , text.lower())
counter = Counter(words)
print ( f "Total words: { len (words) } " )
print ( f "Unique words: { len (counter) } " )
print ( " \n Top 10 most common:" )
for word, count in counter.most_common( 10 ):
print ( f " { word } : { count } " )
# Usage
text = "Python is great. Python is powerful. Python is easy to learn."
analyze_text(text)
LRU Cache Implementation
from collections import OrderedDict
class LRUCache :
def __init__ ( self , capacity ):
self .cache = OrderedDict()
self .capacity = capacity
def get ( self , key ):
if key not in self .cache:
return None
# Move to end (most recently used)
self .cache.move_to_end(key)
return self .cache[key]
def put ( self , key , value ):
if key in self .cache:
self .cache.move_to_end(key)
self .cache[key] = value
if len ( self .cache) > self .capacity:
# Remove least recently used
self .cache.popitem( last = False )
# Usage
cache = LRUCache( 3 )
cache.put( 'a' , 1 )
cache.put( 'b' , 2 )
cache.put( 'c' , 3 )
cache.put( 'd' , 4 ) # 'a' is evicted
Group Items by Property
from collections import defaultdict
data = [
{ 'name' : 'Alice' , 'dept' : 'Engineering' },
{ 'name' : 'Bob' , 'dept' : 'Sales' },
{ 'name' : 'Charlie' , 'dept' : 'Engineering' },
]
# Group by department
by_dept = defaultdict( list )
for person in data:
by_dept[person[ 'dept' ]].append(person[ 'name' ])
print ( dict (by_dept))
# {'Engineering': ['Alice', 'Charlie'], 'Sales': ['Bob']}
Sliding Window Average
from collections import deque
def moving_average ( data , window_size ):
"""Calculate moving average with sliding window"""
window = deque( maxlen = window_size)
averages = []
for value in data:
window.append(value)
if len (window) == window_size:
avg = sum (window) / window_size
averages.append(avg)
return averages
# Usage
data = [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ]
averages = moving_average(data, 3 )
print (averages) # [2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]
Best Practices
Use Counter for frequency analysis:
Counter is optimized for counting and provides useful methods like most_common().from collections import Counter
# Fast and readable
counts = Counter(items)
# Instead of
counts = {}
for item in items:
counts[item] = counts.get(item, 0 ) + 1
Use deque for queues and stacks:
deque has O(1) append and pop from both ends, unlike lists.from collections import deque
# Efficient queue
queue = deque()
queue.append(item) # O(1)
queue.popleft() # O(1)
# List is slower for queues
queue = []
queue.append(item) # O(1)
queue.pop( 0 ) # O(n)
Built-in Types Standard container types
itertools Iterator building blocks
heapq Heap queue algorithm